Initial commit
This commit is contained in:
77
engines/titanic/sound/audio_buffer.cpp
Normal file
77
engines/titanic/sound/audio_buffer.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/audio_buffer.h"
|
||||
#include "common/algorithm.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CAudioBuffer::CAudioBuffer(int maxSize) : _finished(false) {
|
||||
reset();
|
||||
}
|
||||
|
||||
void CAudioBuffer::reset() {
|
||||
_data.clear();
|
||||
}
|
||||
|
||||
void CAudioBuffer::push(int16 value) {
|
||||
enterCriticalSection();
|
||||
_data.push(value);
|
||||
leaveCriticalSection();
|
||||
}
|
||||
|
||||
void CAudioBuffer::push(const int16 *values, int count) {
|
||||
enterCriticalSection();
|
||||
|
||||
for (; count > 0; --count, ++values)
|
||||
_data.push(*values);
|
||||
|
||||
leaveCriticalSection();
|
||||
}
|
||||
|
||||
int16 CAudioBuffer::pop() {
|
||||
enterCriticalSection();
|
||||
int16 value = _data.pop();
|
||||
leaveCriticalSection();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int CAudioBuffer::read(int16 *values, int count) {
|
||||
enterCriticalSection();
|
||||
|
||||
int bytesRead = 0;
|
||||
for (; count > 0 && !_data.empty(); --count, ++bytesRead)
|
||||
*values++ = _data.pop();
|
||||
|
||||
leaveCriticalSection();
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
void CAudioBuffer::enterCriticalSection() {
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
void CAudioBuffer::leaveCriticalSection() {
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
109
engines/titanic/sound/audio_buffer.h
Normal file
109
engines/titanic/sound/audio_buffer.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_AUDIO_BUFFER_H
|
||||
#define TITANIC_AUDIO_BUFFER_H
|
||||
|
||||
#include "titanic/support/fixed_queue.h"
|
||||
#include "common/mutex.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
#define AUDIO_SAMPLING_RATE 22050
|
||||
|
||||
class CAudioBuffer {
|
||||
private:
|
||||
Common::Mutex _mutex;
|
||||
FixedQueue<int16, AUDIO_SAMPLING_RATE * 4> _data;
|
||||
private:
|
||||
/**
|
||||
* Enters a critical section
|
||||
*/
|
||||
void enterCriticalSection();
|
||||
|
||||
/**
|
||||
* Leave a critical section
|
||||
*/
|
||||
void leaveCriticalSection();
|
||||
private:
|
||||
bool _finished;
|
||||
public:
|
||||
CAudioBuffer(int maxSize);
|
||||
|
||||
/**
|
||||
* Resets the audio buffer
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Returns true if the buffer is empty
|
||||
*/
|
||||
bool empty() const { return _data.empty(); }
|
||||
|
||||
/**
|
||||
* Returns the number of 16-bit entries in the buffer
|
||||
*/
|
||||
int size() const { return _data.size(); }
|
||||
|
||||
/**
|
||||
* Returns the number of entries free in the buffer
|
||||
*/
|
||||
int freeSize() const { return _data.freeSize(); }
|
||||
|
||||
/**
|
||||
* Returns true if the buffer is full
|
||||
*/
|
||||
bool full() const { return _data.full(); }
|
||||
|
||||
/**
|
||||
* Returns true if the audio buffering is finished
|
||||
*/
|
||||
bool isFinished() const { return _finished && empty(); }
|
||||
|
||||
/**
|
||||
* Adds a value to the buffer
|
||||
*/
|
||||
void push(int16 value);
|
||||
|
||||
/**
|
||||
* Adds a value to the buffer
|
||||
*/
|
||||
void push(const int16 *values, int count);
|
||||
|
||||
/**
|
||||
* Removes a value from the buffer
|
||||
*/
|
||||
int16 pop();
|
||||
|
||||
/**
|
||||
* Reads out a specified number of samples
|
||||
*/
|
||||
int read(int16 *values, int count);
|
||||
|
||||
/**
|
||||
* Marks the buffer as finishing, and that no more new data will arrive
|
||||
*/
|
||||
void finalize() { _finished = true; }
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_AUDIO_BUFFER_H */
|
||||
74
engines/titanic/sound/auto_music_player.cpp
Normal file
74
engines/titanic/sound/auto_music_player.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/auto_music_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAutoMusicPlayer, CAutoMusicPlayerBase)
|
||||
ON_MESSAGE(EnterRoomMsg)
|
||||
ON_MESSAGE(LeaveRoomMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CAutoMusicPlayer::CAutoMusicPlayer() : CAutoMusicPlayerBase() {
|
||||
}
|
||||
|
||||
void CAutoMusicPlayer::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeQuotedLine(_leaveRoomSound, indent);
|
||||
|
||||
CAutoMusicPlayerBase::save(file, indent);
|
||||
}
|
||||
|
||||
void CAutoMusicPlayer::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_leaveRoomSound = file->readString();
|
||||
|
||||
CAutoMusicPlayerBase::load(file);
|
||||
}
|
||||
|
||||
bool CAutoMusicPlayer::EnterRoomMsg(CEnterRoomMsg *msg) {
|
||||
if (!_isEnabled) {
|
||||
CRoomItem *room = findRoom();
|
||||
if (msg->_newRoom == room)
|
||||
addTimer(2000);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAutoMusicPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) {
|
||||
if (_isEnabled) {
|
||||
CRoomItem *room = findRoom();
|
||||
if (msg->_oldRoom == room) {
|
||||
CChangeMusicMsg changeMsg;
|
||||
changeMsg._action = MUSIC_STOP;
|
||||
changeMsg.execute(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_leaveRoomSound.empty())
|
||||
playSound(_leaveRoomSound);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
53
engines/titanic/sound/auto_music_player.h
Normal file
53
engines/titanic/sound/auto_music_player.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_AUTO_MUSIC_PLAYER_H
|
||||
#define TITANIC_AUTO_MUSIC_PLAYER_H
|
||||
|
||||
#include "titanic/sound/auto_music_player_base.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CAutoMusicPlayer : public CAutoMusicPlayerBase {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool EnterRoomMsg(CEnterRoomMsg *msg);
|
||||
bool LeaveRoomMsg(CLeaveRoomMsg *msg);
|
||||
private:
|
||||
CString _leaveRoomSound;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CAutoMusicPlayer();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_AUTO_MUSIC_PLAYER_H */
|
||||
114
engines/titanic/sound/auto_music_player_base.cpp
Normal file
114
engines/titanic/sound/auto_music_player_base.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/auto_music_player_base.h"
|
||||
#include "titanic/game_manager.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAutoMusicPlayerBase, CGameObject)
|
||||
ON_MESSAGE(StatusChangeMsg)
|
||||
ON_MESSAGE(TimerMsg)
|
||||
ON_MESSAGE(LoadSuccessMsg)
|
||||
ON_MESSAGE(ChangeMusicMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CAutoMusicPlayerBase::CAutoMusicPlayerBase() : CGameObject(),
|
||||
_initialMute(true), _isEnabled(false), _volumeMode(VOL_NORMAL), _transition(1) {
|
||||
}
|
||||
void CAutoMusicPlayerBase::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeQuotedLine(_filename, indent);
|
||||
file->writeNumberLine(_initialMute, indent);
|
||||
file->writeNumberLine(_isEnabled, indent);
|
||||
file->writeNumberLine(_volumeMode, indent);
|
||||
file->writeNumberLine(_transition, indent);
|
||||
|
||||
CGameObject::save(file, indent);
|
||||
}
|
||||
|
||||
void CAutoMusicPlayerBase::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_filename = file->readString();
|
||||
_initialMute = file->readNumber();
|
||||
_isEnabled = file->readNumber();
|
||||
_volumeMode = (VolumeMode)file->readNumber();
|
||||
_transition = file->readNumber();
|
||||
|
||||
CGameObject::load(file);
|
||||
}
|
||||
|
||||
bool CAutoMusicPlayerBase::StatusChangeMsg(CStatusChangeMsg *msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAutoMusicPlayerBase::TimerMsg(CTimerMsg *msg) {
|
||||
CChangeMusicMsg musicMsg;
|
||||
musicMsg._action = MUSIC_START;
|
||||
musicMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAutoMusicPlayerBase::LoadSuccessMsg(CLoadSuccessMsg *msg) {
|
||||
if (_isEnabled) {
|
||||
// WORKAROUND: A problem was encountered with the EmbLobby music player
|
||||
// not getting turned off when room was left, so was turned on again
|
||||
// when loading a savegame elsewhere. This guards against it
|
||||
CRoomItem *newRoom = getGameManager()->getRoom();
|
||||
if (findRoom() != newRoom) {
|
||||
_isEnabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
playAmbientSound(_filename, _volumeMode, _initialMute, true, 0,
|
||||
Audio::Mixer::kMusicSoundType);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAutoMusicPlayerBase::ChangeMusicMsg(CChangeMusicMsg *msg) {
|
||||
if (_isEnabled && msg->_action == MUSIC_STOP) {
|
||||
_isEnabled = false;
|
||||
stopAmbientSound(_transition, -1);
|
||||
}
|
||||
|
||||
if (!msg->_filename.empty()) {
|
||||
_filename = msg->_filename;
|
||||
|
||||
if (_isEnabled) {
|
||||
stopAmbientSound(_transition, -1);
|
||||
playAmbientSound(_filename, _volumeMode, _initialMute, true, 0,
|
||||
Audio::Mixer::kMusicSoundType);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_isEnabled && msg->_action == MUSIC_START) {
|
||||
_isEnabled = true;
|
||||
playAmbientSound(_filename, _volumeMode, _initialMute, true, 0,
|
||||
Audio::Mixer::kMusicSoundType);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
58
engines/titanic/sound/auto_music_player_base.h
Normal file
58
engines/titanic/sound/auto_music_player_base.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_AUTO_MUSIC_PLAYER_BASE_H
|
||||
#define TITANIC_AUTO_MUSIC_PLAYER_BASE_H
|
||||
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CAutoMusicPlayerBase : public CGameObject {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool StatusChangeMsg(CStatusChangeMsg *msg);
|
||||
bool TimerMsg(CTimerMsg *msg);
|
||||
bool LoadSuccessMsg(CLoadSuccessMsg *msg);
|
||||
bool ChangeMusicMsg(CChangeMusicMsg *msg);
|
||||
protected:
|
||||
CString _filename;
|
||||
bool _initialMute;
|
||||
bool _isEnabled;
|
||||
VolumeMode _volumeMode;
|
||||
int _transition;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CAutoMusicPlayerBase();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_AUTO_MUSIC_PLAYER_BASE_H */
|
||||
133
engines/titanic/sound/auto_sound_player.cpp
Normal file
133
engines/titanic/sound/auto_sound_player.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/auto_sound_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAutoSoundPlayer, CGameObject)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(TurnOff)
|
||||
ON_MESSAGE(SignalObject)
|
||||
ON_MESSAGE(SetVolumeMsg)
|
||||
ON_MESSAGE(LoadSuccessMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CAutoSoundPlayer::CAutoSoundPlayer() : CGameObject(),
|
||||
_unused(0), _volume(70), _balance(0), _repeated(false), _soundHandle(-1),
|
||||
_stopSeconds(0), _startSeconds(-1), _active(false), _isVectorSound(false) {
|
||||
}
|
||||
|
||||
void CAutoSoundPlayer::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_unused, indent);
|
||||
file->writeQuotedLine(_filename, indent);
|
||||
file->writeNumberLine(_volume, indent);
|
||||
file->writeNumberLine(_balance, indent);
|
||||
file->writeNumberLine(_repeated, indent);
|
||||
file->writeNumberLine(_soundHandle, indent);
|
||||
file->writeNumberLine(_stopSeconds, indent);
|
||||
file->writeNumberLine(_startSeconds, indent);
|
||||
file->writeNumberLine(_active, indent);
|
||||
file->writeNumberLine(_isVectorSound, indent);
|
||||
|
||||
CGameObject::save(file, indent);
|
||||
}
|
||||
|
||||
void CAutoSoundPlayer::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_unused = file->readNumber();
|
||||
_filename = file->readString();
|
||||
_volume = file->readNumber();
|
||||
_balance = file->readNumber();
|
||||
_repeated = file->readNumber();
|
||||
_soundHandle = file->readNumber();
|
||||
_stopSeconds = file->readNumber();
|
||||
_startSeconds = file->readNumber();
|
||||
_active = file->readNumber();
|
||||
_isVectorSound = file->readNumber();
|
||||
|
||||
CGameObject::load(file);
|
||||
}
|
||||
|
||||
bool CAutoSoundPlayer::TurnOn(CTurnOn *msg) {
|
||||
if (_soundHandle == -1) {
|
||||
CProximity prox;
|
||||
prox._balance = _balance;
|
||||
prox._repeated = _repeated;
|
||||
if (_isVectorSound)
|
||||
prox._positioningMode = POSMODE_VECTOR;
|
||||
prox._channelVolume = (_startSeconds == -1) ? _volume : 0;
|
||||
|
||||
_soundHandle = playSound(_filename, prox);
|
||||
if (_startSeconds != -1)
|
||||
setSoundVolume(_soundHandle, _volume, _startSeconds);
|
||||
|
||||
_active = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAutoSoundPlayer::TurnOff(CTurnOff *msg) {
|
||||
if (_soundHandle != -1) {
|
||||
if (isSoundActive(_soundHandle))
|
||||
stopSound(_soundHandle, _stopSeconds);
|
||||
|
||||
_soundHandle = -1;
|
||||
_active = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAutoSoundPlayer::SignalObject(CSignalObject *msg) {
|
||||
if (_soundHandle != -1) {
|
||||
if (isSoundActive(_soundHandle))
|
||||
stopSound(_soundHandle, msg->_numValue);
|
||||
|
||||
_soundHandle = -1;
|
||||
_active = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAutoSoundPlayer::SetVolumeMsg(CSetVolumeMsg *msg) {
|
||||
if (_soundHandle != -1 && isSoundActive(_soundHandle))
|
||||
setSoundVolume(_soundHandle, msg->_volume, msg->_secondsTransition);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAutoSoundPlayer::LoadSuccessMsg(CLoadSuccessMsg *msg) {
|
||||
if (_active) {
|
||||
_soundHandle = -1;
|
||||
_active = false;
|
||||
|
||||
CTurnOn onMsg;
|
||||
onMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
64
engines/titanic/sound/auto_sound_player.h
Normal file
64
engines/titanic/sound/auto_sound_player.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_AUTO_SOUND_PLAYER_H
|
||||
#define TITANIC_AUTO_SOUND_PLAYER_H
|
||||
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CAutoSoundPlayer : public CGameObject {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool TurnOff(CTurnOff *msg);
|
||||
bool SignalObject(CSignalObject *msg);
|
||||
bool SetVolumeMsg(CSetVolumeMsg *msg);
|
||||
bool LoadSuccessMsg(CLoadSuccessMsg *msg);
|
||||
public:
|
||||
int _unused;
|
||||
CString _filename;
|
||||
int _volume;
|
||||
int _balance;
|
||||
bool _repeated;
|
||||
int _soundHandle;
|
||||
int _stopSeconds;
|
||||
int _startSeconds;
|
||||
bool _active;
|
||||
bool _isVectorSound;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CAutoSoundPlayer();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_AUTO_SOUND_PLAYER_H */
|
||||
78
engines/titanic/sound/auto_sound_player_adsr.cpp
Normal file
78
engines/titanic/sound/auto_sound_player_adsr.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/auto_sound_player_adsr.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CAutoSoundPlayerADSR, CAutoSoundPlayer)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(TurnOff)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CAutoSoundPlayerADSR::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeQuotedLine(_soundName1, indent);
|
||||
file->writeQuotedLine(_soundName2, indent);
|
||||
file->writeQuotedLine(_soundName3, indent);
|
||||
CAutoSoundPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CAutoSoundPlayerADSR::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_soundName1 = file->readString();
|
||||
_soundName2 = file->readString();
|
||||
_soundName3 = file->readString();
|
||||
CAutoSoundPlayer::load(file);
|
||||
}
|
||||
|
||||
bool CAutoSoundPlayerADSR::TurnOn(CTurnOn *msg) {
|
||||
if (_soundHandle == -1) {
|
||||
if (!_soundName1.empty()) {
|
||||
_soundHandle = playSound(_soundName1, _volume, _balance);
|
||||
|
||||
if (!_soundName2.empty())
|
||||
_soundHandle = queueSound(_soundName2, _soundHandle, _volume, _balance);
|
||||
|
||||
_soundHandle = queueSound(_filename, _soundHandle, _volume, _balance);
|
||||
_active = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAutoSoundPlayerADSR::TurnOff(CTurnOff *msg) {
|
||||
if (_soundHandle != -1) {
|
||||
if (!_soundName3.empty())
|
||||
queueSound(_soundName3, _soundHandle, _volume, _balance);
|
||||
|
||||
if (isSoundActive(_soundHandle))
|
||||
stopSound(_soundHandle);
|
||||
|
||||
_soundHandle = -1;
|
||||
_active = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
53
engines/titanic/sound/auto_sound_player_adsr.h
Normal file
53
engines/titanic/sound/auto_sound_player_adsr.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_AUTO_SOUND_PLAYER_ADSR_H
|
||||
#define TITANIC_AUTO_SOUND_PLAYER_ADSR_H
|
||||
|
||||
#include "titanic/sound/auto_sound_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CAutoSoundPlayerADSR : public CAutoSoundPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool TurnOff(CTurnOff *msg);
|
||||
private:
|
||||
CString _soundName1;
|
||||
CString _soundName2;
|
||||
CString _soundName3;
|
||||
public:
|
||||
CLASSDEF;
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_AUTO_SOUND_PLAYER_ADSR_H */
|
||||
46
engines/titanic/sound/background_sound_maker.cpp
Normal file
46
engines/titanic/sound/background_sound_maker.cpp
Normal file
@@ -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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/background_sound_maker.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CBackgroundSoundMaker, CGameObject)
|
||||
ON_MESSAGE(FrameMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CBackgroundSoundMaker::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_value, indent);
|
||||
CGameObject::save(file, indent);
|
||||
}
|
||||
|
||||
void CBackgroundSoundMaker::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_value = file->readNumber();
|
||||
CGameObject::load(file);
|
||||
}
|
||||
|
||||
bool CBackgroundSoundMaker::FrameMsg(CFrameMsg *msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
51
engines/titanic/sound/background_sound_maker.h
Normal file
51
engines/titanic/sound/background_sound_maker.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_BACKGROUND_SOUND_MAKER_H
|
||||
#define TITANIC_BACKGROUND_SOUND_MAKER_H
|
||||
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CBackgroundSoundMaker : public CGameObject {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool FrameMsg(CFrameMsg *msg);
|
||||
public:
|
||||
int _value;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CBackgroundSoundMaker() : CGameObject(), _value(0) {}
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_BACKGROUND_SOUND_MAKER_H */
|
||||
55
engines/titanic/sound/bird_song.cpp
Normal file
55
engines/titanic/sound/bird_song.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/bird_song.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CBirdSong, CRoomAutoSoundPlayer)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(SignalObject)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CBirdSong::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_flag, indent);
|
||||
CRoomAutoSoundPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CBirdSong::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_flag = file->readNumber();
|
||||
CRoomAutoSoundPlayer::load(file);
|
||||
}
|
||||
|
||||
bool CBirdSong::TurnOn(CTurnOn *msg) {
|
||||
if (!_flag)
|
||||
CAutoSoundPlayer::TurnOn(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBirdSong::SignalObject(CSignalObject *msg) {
|
||||
_flag = true;
|
||||
CAutoSoundPlayer::SignalObject(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
52
engines/titanic/sound/bird_song.h
Normal file
52
engines/titanic/sound/bird_song.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_BIRD_SONG_H
|
||||
#define TITANIC_BIRD_SONG_H
|
||||
|
||||
#include "titanic/sound/room_auto_sound_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CBirdSong : public CRoomAutoSoundPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool SignalObject(CSignalObject *msg);
|
||||
public:
|
||||
bool _flag;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CBirdSong() : CRoomAutoSoundPlayer(), _flag(false) {}
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_BIRD_SONG_H */
|
||||
46
engines/titanic/sound/dome_from_top_of_well.cpp
Normal file
46
engines/titanic/sound/dome_from_top_of_well.cpp
Normal file
@@ -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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/dome_from_top_of_well.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
EMPTY_MESSAGE_MAP(CDomeFromTopOfWell, CViewAutoSoundPlayer);
|
||||
|
||||
CDomeFromTopOfWell::CDomeFromTopOfWell() : CViewAutoSoundPlayer() {
|
||||
_filename = "z#227.wav";
|
||||
_volume = 25;
|
||||
_repeated = true;
|
||||
_stopSeconds = 1;
|
||||
_startSeconds = 1;
|
||||
}
|
||||
|
||||
void CDomeFromTopOfWell::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
CViewAutoSoundPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CDomeFromTopOfWell::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
CViewAutoSoundPlayer::load(file);
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
48
engines/titanic/sound/dome_from_top_of_well.h
Normal file
48
engines/titanic/sound/dome_from_top_of_well.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_DOME_FROM_TOP_OF_WELL_H
|
||||
#define TITANIC_DOME_FROM_TOP_OF_WELL_H
|
||||
|
||||
#include "titanic/sound/view_auto_sound_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CDomeFromTopOfWell : public CViewAutoSoundPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CDomeFromTopOfWell();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_DOME_FROM_TOP_OF_WELL_H */
|
||||
59
engines/titanic/sound/enter_view_toggles_other_music.cpp
Normal file
59
engines/titanic/sound/enter_view_toggles_other_music.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/enter_view_toggles_other_music.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CEnterViewTogglesOtherMusic, CTriggerAutoMusicPlayer)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CEnterViewTogglesOtherMusic::CEnterViewTogglesOtherMusic() :
|
||||
CTriggerAutoMusicPlayer(), _value(2) {
|
||||
}
|
||||
|
||||
void CEnterViewTogglesOtherMusic::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_value, indent);
|
||||
|
||||
CTriggerAutoMusicPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CEnterViewTogglesOtherMusic::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_value = file->readNumber();
|
||||
|
||||
CTriggerAutoMusicPlayer::load(file);
|
||||
}
|
||||
|
||||
bool CEnterViewTogglesOtherMusic::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
CViewItem *view = findView();
|
||||
if (view == msg->_newView) {
|
||||
CTriggerAutoMusicPlayerMsg triggerMsg;
|
||||
triggerMsg._value = _value;
|
||||
triggerMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
51
engines/titanic/sound/enter_view_toggles_other_music.h
Normal file
51
engines/titanic/sound/enter_view_toggles_other_music.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_ENTER_VIEW_TOGGLES_OTHER_MUSIC_H
|
||||
#define TITANIC_ENTER_VIEW_TOGGLES_OTHER_MUSIC_H
|
||||
|
||||
#include "titanic/sound/trigger_auto_music_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CEnterViewTogglesOtherMusic : public CTriggerAutoMusicPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
protected:
|
||||
int _value;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CEnterViewTogglesOtherMusic();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_ENTER_VIEW_TOGGLES_OTHER_MUSIC_H */
|
||||
93
engines/titanic/sound/gondolier_song.cpp
Normal file
93
engines/titanic/sound/gondolier_song.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/gondolier_song.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CGondolierSong, CRoomAutoSoundPlayer)
|
||||
ON_MESSAGE(TurnOn)
|
||||
ON_MESSAGE(SignalObject)
|
||||
ON_MESSAGE(SetVolumeMsg)
|
||||
ON_MESSAGE(StatusChangeMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CGondolierSong::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(_enabled, indent);
|
||||
file->writeNumberLine(_value, indent);
|
||||
CRoomAutoSoundPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CGondolierSong::load(SimpleFile *file) {
|
||||
_enabled = file->readNumber();
|
||||
_value = file->readNumber();
|
||||
CRoomAutoSoundPlayer::load(file);
|
||||
}
|
||||
|
||||
bool CGondolierSong::TurnOn(CTurnOn *msg) {
|
||||
if (_enabled) {
|
||||
if (_soundHandle != -1) {
|
||||
int volume = _value * _volume / 100;
|
||||
|
||||
if (_startSeconds == -1) {
|
||||
_soundHandle = playSound(_filename, volume, _balance, _repeated);
|
||||
} else {
|
||||
_soundHandle = playSound(_filename, 0, _balance, _repeated);
|
||||
setSoundVolume(_soundHandle, _volume, _startSeconds);
|
||||
}
|
||||
|
||||
_active = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGondolierSong::SignalObject(CSignalObject *msg) {
|
||||
_enabled = false;
|
||||
CAutoSoundPlayer::SignalObject(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGondolierSong::SetVolumeMsg(CSetVolumeMsg *msg) {
|
||||
if (_enabled) {
|
||||
_volume = msg->_volume;
|
||||
|
||||
if (_soundHandle != -1 && isSoundActive(_soundHandle)) {
|
||||
int newVolume = _value * _volume / 100;
|
||||
setSoundVolume(_soundHandle, newVolume, msg->_secondsTransition);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGondolierSong::StatusChangeMsg(CStatusChangeMsg *msg) {
|
||||
if (_enabled) {
|
||||
_value = CLIP(msg->_newStatus, 0, 100);
|
||||
CSetVolumeMsg volumeMsg(_volume, _stopSeconds);
|
||||
volumeMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
55
engines/titanic/sound/gondolier_song.h
Normal file
55
engines/titanic/sound/gondolier_song.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_GONDOLIER_SONG_H
|
||||
#define TITANIC_GONDOLIER_SONG_H
|
||||
|
||||
#include "titanic/sound/room_auto_sound_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CGondolierSong : public CRoomAutoSoundPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool TurnOn(CTurnOn *msg);
|
||||
bool SignalObject(CSignalObject *msg);
|
||||
bool SetVolumeMsg(CSetVolumeMsg *msg);
|
||||
bool StatusChangeMsg(CStatusChangeMsg *msg);
|
||||
public:
|
||||
bool _enabled;
|
||||
int _value;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CGondolierSong() : CRoomAutoSoundPlayer(), _enabled(true), _value(0) {}
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_GONDOLIER_SONG_H */
|
||||
185
engines/titanic/sound/music_player.cpp
Normal file
185
engines/titanic/sound/music_player.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/music_player.h"
|
||||
#include "titanic/sound/music_room.h"
|
||||
#include "titanic/translation.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(_isActive, indent);
|
||||
file->writeQuotedLine(_stopTarget, indent);
|
||||
file->writeNumberLine(_musicActive, indent);
|
||||
file->writeNumberLine(_volume, indent);
|
||||
|
||||
CGameObject::save(file, indent);
|
||||
}
|
||||
|
||||
void CMusicPlayer::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_isActive = file->readNumber();
|
||||
_stopTarget = file->readString();
|
||||
_musicActive = file->readNumber();
|
||||
_volume = 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()->setupMusic(_volume);
|
||||
_isActive = true;
|
||||
unlockMouse();
|
||||
}
|
||||
|
||||
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->update()) {
|
||||
getMusicRoom()->stopMusic();
|
||||
_isActive = false;
|
||||
|
||||
CMusicHasStoppedMsg stoppedMsg;
|
||||
stoppedMsg.execute(_stopTarget);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMusicPlayer::EnterRoomMsg(CEnterRoomMsg *msg) {
|
||||
// Set up a timer that will create a music handler
|
||||
addTimer(100);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMusicPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) {
|
||||
getMusicRoom()->destroyMusicHandler();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMusicPlayer::CreateMusicPlayerMsg(CCreateMusicPlayerMsg *msg) {
|
||||
if (CMusicRoom::_musicHandler) {
|
||||
CMusicRoom::_musicHandler->setActive(_musicActive);
|
||||
return true;
|
||||
}
|
||||
|
||||
CMusicRoomHandler *musicHandler = getMusicRoom()->createMusicHandler();
|
||||
CMusicRoomInstrument *ins;
|
||||
|
||||
if (musicHandler) {
|
||||
ins = musicHandler->createInstrument(BELLS, 3);
|
||||
ins->load(0, TRANSLATE("z#490.wav", "z#227.wav"), 60);
|
||||
ins->load(1, TRANSLATE("z#488.wav", "z#225.wav"), 62);
|
||||
ins->load(2, TRANSLATE("z#489.wav", "z#226.wav"), 63);
|
||||
|
||||
ins = musicHandler->createInstrument(SNAKE, 5);
|
||||
ins->load(0, TRANSLATE("z#493.wav", "z#230.wav"), 22);
|
||||
ins->load(1, TRANSLATE("z#495.wav", "z#232.wav"), 29);
|
||||
ins->load(2, TRANSLATE("z#492.wav", "z#229.wav"), 34);
|
||||
ins->load(3, TRANSLATE("z#494.wav", "z#231.wav"), 41);
|
||||
ins->load(4, TRANSLATE("z#491.wav", "z#228.wav"), 46);
|
||||
|
||||
ins = musicHandler->createInstrument(PIANO, 5);
|
||||
ins->load(0, TRANSLATE("z#499.wav", "z#236.wav"), 26);
|
||||
ins->load(1, TRANSLATE("z#497.wav", "z#234.wav"), 34);
|
||||
ins->load(2, TRANSLATE("z#498.wav", "z#235.wav"), 38);
|
||||
ins->load(3, TRANSLATE("z#496.wav", "z#233.wav"), 46);
|
||||
ins->load(4, TRANSLATE("z#500.wav", "z#237.wav"), 60);
|
||||
|
||||
ins = musicHandler->createInstrument(BASS, 7);
|
||||
ins->load(0, TRANSLATE("z#504.wav", "z#241.wav"), 22);
|
||||
ins->load(1, TRANSLATE("z#507.wav", "z#244.wav"), 29);
|
||||
ins->load(2, TRANSLATE("z#503.wav", "z#240.wav"), 34);
|
||||
ins->load(3, TRANSLATE("z#506.wav", "z#243.wav"), 41);
|
||||
ins->load(4, TRANSLATE("z#502.wav", "z#239.wav"), 46);
|
||||
ins->load(5, TRANSLATE("z#505.wav", "z#242.wav"), 53);
|
||||
ins->load(6, TRANSLATE("z#501.wav", "z#238.wav"), 58);
|
||||
|
||||
CMusicRoom::_musicHandler->setActive(_musicActive);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMusicPlayer::TimerMsg(CTimerMsg *msg) {
|
||||
CCreateMusicPlayerMsg playerMsg;
|
||||
playerMsg.execute(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMusicPlayer::LoadSuccessMsg(CLoadSuccessMsg *msg) {
|
||||
if (_isActive) {
|
||||
// Music is meant to be playing, so restart it
|
||||
CStopMusicMsg stopMsg;
|
||||
stopMsg.execute(this);
|
||||
CStartMusicMsg startMsg;
|
||||
startMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
63
engines/titanic/sound/music_player.h
Normal file
63
engines/titanic/sound/music_player.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_MUSIC_PLAYER_H
|
||||
#define TITANIC_MUSIC_PLAYER_H
|
||||
|
||||
#include "titanic/core/game_object.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
|
||||
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:
|
||||
bool _isActive;
|
||||
CString _stopTarget;
|
||||
bool _musicActive;
|
||||
int _volume;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CMusicPlayer() : CGameObject(),
|
||||
_isActive(false), _musicActive(false), _volume(100) {}
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MUSIC_PLAYER_H */
|
||||
97
engines/titanic/sound/music_room.cpp
Normal file
97
engines/titanic/sound/music_room.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/textconsole.h"
|
||||
#include "titanic/sound/music_room.h"
|
||||
#include "titanic/sound/sound.h"
|
||||
#include "titanic/game_manager.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CMusicRoomHandler *CMusicRoom::_musicHandler;
|
||||
|
||||
CMusicRoom::CMusicRoom(CGameManager *gameManager) :
|
||||
_gameManager(gameManager) {
|
||||
_sound = &_gameManager->_sound;
|
||||
}
|
||||
|
||||
CMusicRoom::~CMusicRoom() {
|
||||
destroyMusicHandler();
|
||||
}
|
||||
|
||||
CMusicRoomHandler *CMusicRoom::createMusicHandler() {
|
||||
if (_musicHandler)
|
||||
destroyMusicHandler();
|
||||
|
||||
_musicHandler = new CMusicRoomHandler(_gameManager->_project, &_sound->_soundManager);
|
||||
return _musicHandler;
|
||||
}
|
||||
|
||||
void CMusicRoom::destroyMusicHandler() {
|
||||
delete _musicHandler;
|
||||
_musicHandler = nullptr;
|
||||
}
|
||||
|
||||
void CMusicRoom::setupMusic(int volume) {
|
||||
if (_musicHandler) {
|
||||
// Set up the control values that form the correct settings
|
||||
_musicHandler->setSpeedControl2(BELLS, 0);
|
||||
_musicHandler->setSpeedControl2(SNAKE, 1);
|
||||
_musicHandler->setSpeedControl2(PIANO, -1);
|
||||
_musicHandler->setSpeedControl2(BASS, -2);
|
||||
|
||||
_musicHandler->setPitchControl2(BELLS, 1);
|
||||
_musicHandler->setPitchControl2(SNAKE, 2);
|
||||
_musicHandler->setPitchControl2(PIANO, 0);
|
||||
_musicHandler->setPitchControl2(BASS, 1);
|
||||
|
||||
_musicHandler->setInversionControl2(BELLS, true);
|
||||
_musicHandler->setInversionControl2(SNAKE, false);
|
||||
_musicHandler->setInversionControl2(PIANO, true);
|
||||
_musicHandler->setInversionControl2(BASS, false);
|
||||
|
||||
_musicHandler->setDirectionControl2(BELLS, false);
|
||||
_musicHandler->setDirectionControl2(SNAKE, false);
|
||||
_musicHandler->setDirectionControl2(PIANO, true);
|
||||
_musicHandler->setDirectionControl2(BASS, true);
|
||||
|
||||
// Set up the current control values
|
||||
for (MusicInstrument idx = BELLS; idx <= BASS;
|
||||
idx = (MusicInstrument)((int)idx + 1)) {
|
||||
MusicRoomInstrument &instr = _instruments[idx];
|
||||
_musicHandler->setSpeedControl(idx, instr._speedControl);
|
||||
_musicHandler->setPitchControl(idx, instr._pitchControl);
|
||||
_musicHandler->setDirectionControl(idx, instr._directionControl);
|
||||
_musicHandler->setInversionControl(idx, instr._inversionControl);
|
||||
_musicHandler->setMuteControl(idx, instr._muteControl);
|
||||
}
|
||||
|
||||
// Set up the music handler
|
||||
_musicHandler->setup(volume);
|
||||
}
|
||||
}
|
||||
|
||||
void CMusicRoom::stopMusic() {
|
||||
if (_musicHandler)
|
||||
_musicHandler->stop();
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
103
engines/titanic/sound/music_room.h
Normal file
103
engines/titanic/sound/music_room.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_MUSIC_ROOM_H
|
||||
#define TITANIC_MUSIC_ROOM_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "titanic/sound/music_room_handler.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CGameManager;
|
||||
class CSound;
|
||||
|
||||
class CMusicRoom {
|
||||
private:
|
||||
MusicRoomInstrument _instruments[4];
|
||||
public:
|
||||
static CMusicRoomHandler *_musicHandler;
|
||||
public:
|
||||
CGameManager *_gameManager;
|
||||
CSound *_sound;
|
||||
public:
|
||||
CMusicRoom(CGameManager *owner);
|
||||
~CMusicRoom();
|
||||
|
||||
/**
|
||||
* Creates a music handler
|
||||
*/
|
||||
CMusicRoomHandler *createMusicHandler();
|
||||
|
||||
/**
|
||||
* Destroys and currently active music handler
|
||||
*/
|
||||
void destroyMusicHandler();
|
||||
|
||||
/**
|
||||
* Sets the speed control for a given instrument
|
||||
*/
|
||||
void setSpeedControl(MusicInstrument instrument, int val) {
|
||||
_instruments[instrument]._speedControl = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pitch control for a given instrument
|
||||
*/
|
||||
void setPitchControl(MusicInstrument instrument, int val) {
|
||||
_instruments[instrument]._pitchControl = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the direction control for a given instrument
|
||||
*/
|
||||
void setDirectionControl(MusicInstrument instrument, bool val) {
|
||||
_instruments[instrument]._directionControl = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the inversion control for a given instrument
|
||||
*/
|
||||
void setInversionControl(MusicInstrument instrument, bool val) {
|
||||
_instruments[instrument]._inversionControl = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mute control for a given instrument
|
||||
*/
|
||||
void setMuteControl(MusicInstrument instrument, bool val) {
|
||||
_instruments[instrument]._muteControl = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the music controls
|
||||
*/
|
||||
void setupMusic(int volume);
|
||||
|
||||
/**
|
||||
* Stop playing music
|
||||
*/
|
||||
void stopMusic();
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MUSIC_ROOM_H */
|
||||
347
engines/titanic/sound/music_room_handler.cpp
Normal file
347
engines/titanic/sound/music_room_handler.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/music_room_handler.h"
|
||||
#include "titanic/sound/sound_manager.h"
|
||||
#include "titanic/events.h"
|
||||
#include "titanic/core/project_item.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CMusicRoomHandler::CMusicRoomHandler(CProjectItem *project, CSoundManager *soundManager) :
|
||||
_project(project), _soundManager(soundManager), _active(false),
|
||||
_soundHandle(-1), _waveFile(nullptr), _volume(100) {
|
||||
_instrumentsActive = 0;
|
||||
_isPlaying = false;
|
||||
_startTicks = _soundStartTicks = 0;
|
||||
Common::fill(&_instruments[0], &_instruments[4], (CMusicRoomInstrument *)nullptr);
|
||||
for (int idx = 0; idx < 4; ++idx)
|
||||
_songs[idx] = new CMusicSong(idx);
|
||||
Common::fill(&_startPos[0], &_startPos[4], 0);
|
||||
Common::fill(&_animExpiryTime[0], &_animExpiryTime[4], 0.0);
|
||||
Common::fill(&_position[0], &_position[4], 0);
|
||||
|
||||
_audioBuffer = new CAudioBuffer(88200);
|
||||
}
|
||||
|
||||
CMusicRoomHandler::~CMusicRoomHandler() {
|
||||
stop();
|
||||
for (int idx = 0; idx < 4; ++idx)
|
||||
delete _songs[idx];
|
||||
|
||||
delete _audioBuffer;
|
||||
}
|
||||
|
||||
CMusicRoomInstrument *CMusicRoomHandler::createInstrument(MusicInstrument instrument, int count) {
|
||||
switch (instrument) {
|
||||
case BELLS:
|
||||
_instruments[BELLS] = new CMusicRoomInstrument(_project, _soundManager, MV_BELLS);
|
||||
break;
|
||||
case SNAKE:
|
||||
_instruments[SNAKE] = new CMusicRoomInstrument(_project, _soundManager, MV_SNAKE);
|
||||
break;
|
||||
case PIANO:
|
||||
_instruments[PIANO] = new CMusicRoomInstrument(_project, _soundManager, MV_PIANO);
|
||||
break;
|
||||
case BASS:
|
||||
_instruments[BASS] = new CMusicRoomInstrument(_project, _soundManager, MV_BASS);
|
||||
break;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
_instruments[instrument]->setFilesCount(count);
|
||||
return _instruments[instrument];
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::setup(int volume) {
|
||||
_volume = volume;
|
||||
_audioBuffer->reset();
|
||||
|
||||
for (int idx = 0; idx < 4; ++idx) {
|
||||
MusicRoomInstrument &ins1 = _array1[idx];
|
||||
MusicRoomInstrument &ins2 = _array2[idx];
|
||||
|
||||
if (ins1._directionControl == ins2._directionControl) {
|
||||
_startPos[idx] = 0;
|
||||
} else {
|
||||
_startPos[idx] = _songs[idx]->size() - 1;
|
||||
}
|
||||
|
||||
_position[idx] = _startPos[idx];
|
||||
_animExpiryTime[idx] = 0.0;
|
||||
}
|
||||
|
||||
_instrumentsActive = 4;
|
||||
_isPlaying = true;
|
||||
update();
|
||||
|
||||
_waveFile = _soundManager->loadMusic(_audioBuffer, DisposeAfterUse::NO);
|
||||
update();
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::stop() {
|
||||
if (_waveFile) {
|
||||
_soundManager->stopSound(_soundHandle);
|
||||
delete _waveFile;
|
||||
_waveFile = nullptr;
|
||||
_soundHandle = -1;
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < 4; ++idx) {
|
||||
_instruments[idx]->clear();
|
||||
if (_active && _instruments[idx])
|
||||
_instruments[idx]->stop();
|
||||
}
|
||||
|
||||
_instrumentsActive = 0;
|
||||
_isPlaying = false;
|
||||
_startTicks = _soundStartTicks = 0;
|
||||
}
|
||||
|
||||
bool CMusicRoomHandler::checkInstrument(MusicInstrument instrument) const {
|
||||
return (_array1[instrument]._speedControl + _array2[instrument]._speedControl) == 0
|
||||
&& (_array1[instrument]._pitchControl + _array2[instrument]._pitchControl) == 0
|
||||
&& _array1[instrument]._directionControl == _array2[instrument]._directionControl
|
||||
&& _array1[instrument]._inversionControl == _array2[instrument]._inversionControl
|
||||
&& _array1[instrument]._muteControl == _array2[instrument]._muteControl;
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::setSpeedControl2(MusicInstrument instrument, int value) {
|
||||
if (instrument >= BELLS && instrument <= BASS && value >= -2 && value <= 2)
|
||||
_array2[instrument]._speedControl = value;
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::setPitchControl2(MusicInstrument instrument, int value) {
|
||||
if (instrument >= BELLS && instrument <= BASS && value >= -2 && value <= 2)
|
||||
_array2[instrument]._pitchControl = value * 3;
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::setInversionControl2(MusicInstrument instrument, bool value) {
|
||||
if (instrument >= BELLS && instrument <= BASS)
|
||||
_array2[instrument]._inversionControl = value;
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::setDirectionControl2(MusicInstrument instrument, bool value) {
|
||||
if (instrument >= BELLS && instrument <= BASS)
|
||||
_array2[instrument]._directionControl = value;
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::setPitchControl(MusicInstrument instrument, int value) {
|
||||
if (instrument >= BELLS && instrument <= BASS && value >= -2 && value <= 2)
|
||||
_array1[instrument]._pitchControl = value * 3;
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::setSpeedControl(MusicInstrument instrument, int value) {
|
||||
if (instrument >= BELLS && instrument <= BASS && value >= -2 && value <= 2)
|
||||
_array1[instrument]._speedControl = value;
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::setDirectionControl(MusicInstrument instrument, bool value) {
|
||||
if (instrument >= BELLS && instrument <= BASS)
|
||||
_array1[instrument]._directionControl = value;
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::setInversionControl(MusicInstrument instrument, bool value) {
|
||||
if (instrument >= BELLS && instrument <= BASS)
|
||||
_array1[instrument]._inversionControl = value;
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::setMuteControl(MusicInstrument instrument, bool value) {
|
||||
if (instrument >= BELLS && instrument <= BASS)
|
||||
_array1[instrument]._muteControl = value;
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::start() {
|
||||
if (_active) {
|
||||
for (int idx = 0; idx < 4; ++idx)
|
||||
_instruments[idx]->start();
|
||||
}
|
||||
}
|
||||
|
||||
bool CMusicRoomHandler::update() {
|
||||
uint currentTicks = g_system->getMillis();
|
||||
|
||||
if (!_startTicks) {
|
||||
start();
|
||||
_startTicks = currentTicks;
|
||||
} else if (!_soundStartTicks && currentTicks >= (_startTicks + 3000)) {
|
||||
if (_waveFile) {
|
||||
CProximity prox;
|
||||
prox._channelVolume = _volume;
|
||||
_soundHandle = _soundManager->playSound(*_waveFile, prox);
|
||||
}
|
||||
|
||||
_soundStartTicks = currentTicks;
|
||||
}
|
||||
|
||||
if (_instrumentsActive > 0) {
|
||||
updateAudio();
|
||||
updateInstruments();
|
||||
}
|
||||
|
||||
return !_audioBuffer->isFinished();
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::updateAudio() {
|
||||
int size = _audioBuffer->freeSize();
|
||||
int count;
|
||||
int16 *ptr;
|
||||
|
||||
if (size > 0) {
|
||||
// Create a temporary buffer for merging the instruments into
|
||||
int16 *audioData = new int16[size];
|
||||
Common::fill(audioData, audioData + size, 0);
|
||||
|
||||
for (MusicInstrument instrument = BELLS; instrument <= BASS;
|
||||
instrument = (MusicInstrument)((int)instrument + 1)) {
|
||||
CMusicRoomInstrument *musicWave = _instruments[instrument];
|
||||
|
||||
// Iterate through each of the four instruments and do an additive
|
||||
// read that will merge their data onto the output buffer
|
||||
for (count = size, ptr = audioData; count > 0; ) {
|
||||
int amount = musicWave->read(ptr, count * 2);
|
||||
if (amount > 0) {
|
||||
count -= amount / sizeof(uint16);
|
||||
ptr += amount / sizeof(uint16);
|
||||
} else if (!pollInstrument(instrument)) {
|
||||
--_instrumentsActive;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_audioBuffer->push(audioData, size);
|
||||
delete[] audioData;
|
||||
}
|
||||
|
||||
if (_instrumentsActive == 0)
|
||||
// Reaching end of music
|
||||
_audioBuffer->finalize();
|
||||
}
|
||||
|
||||
void CMusicRoomHandler::updateInstruments() {
|
||||
uint currentTicks = g_system->getMillis();
|
||||
|
||||
if (_active && _soundStartTicks) {
|
||||
for (MusicInstrument instrument = BELLS; instrument <= BASS;
|
||||
instrument = (MusicInstrument)((int)instrument + 1)) {
|
||||
MusicRoomInstrument &ins1 = _array1[instrument];
|
||||
MusicRoomInstrument &ins2 = _array2[instrument];
|
||||
CMusicRoomInstrument *ins = _instruments[instrument];
|
||||
|
||||
// Is this about checking playback position?
|
||||
if (_position[instrument] < 0 || ins1._muteControl || _position[instrument] >= _songs[instrument]->size()) {
|
||||
_position[instrument] = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
double time = (double)(currentTicks - _soundStartTicks) / 1000.0 - 0.6;
|
||||
double threshold = _animExpiryTime[instrument] - ins->_insStartTime;
|
||||
|
||||
if (time >= threshold) {
|
||||
_animExpiryTime[instrument] += getAnimDuration(instrument, _position[instrument]);
|
||||
|
||||
const CValuePair &vp = (*_songs[instrument])[_position[instrument]];
|
||||
if (vp._data != 0x7FFFFFFF) {
|
||||
int amount = getPitch(instrument, _position[instrument]);
|
||||
_instruments[instrument]->update(amount);
|
||||
}
|
||||
|
||||
if (ins1._directionControl == ins2._directionControl) {
|
||||
_position[instrument]++;
|
||||
} else {
|
||||
_position[instrument]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CMusicRoomHandler::pollInstrument(MusicInstrument instrument) {
|
||||
int &arrIndex = _startPos[instrument];
|
||||
if (arrIndex < 0) {
|
||||
_instruments[instrument]->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
const CMusicSong &song = *_songs[instrument];
|
||||
if (arrIndex >= song.size()) {
|
||||
arrIndex = -1;
|
||||
_instruments[instrument]->clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
const CValuePair &vp = song[arrIndex];
|
||||
uint duration = static_cast<int>(getAnimDuration(instrument, arrIndex) * 44100.0) & ~1;
|
||||
|
||||
if (vp._data == 0x7FFFFFFF || _array1[instrument]._muteControl)
|
||||
_instruments[instrument]->reset(duration);
|
||||
else
|
||||
_instruments[instrument]->chooseWaveFile(getPitch(instrument, arrIndex), duration);
|
||||
|
||||
if (_array1[instrument]._directionControl == _array2[instrument]._directionControl) {
|
||||
++arrIndex;
|
||||
} else {
|
||||
--arrIndex;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
double CMusicRoomHandler::getAnimDuration(MusicInstrument instrument, int arrIndex) {
|
||||
const CValuePair &vp = (*_songs[instrument])[arrIndex];
|
||||
|
||||
switch (_array1[instrument]._speedControl + _array2[instrument]._speedControl + 3) {
|
||||
case 0:
|
||||
return (double)vp._length * 1.5 * 0.0625 * 0.46875;
|
||||
case 1:
|
||||
return (double)vp._length * 1.33 * 0.0625 * 0.46875;
|
||||
case 2:
|
||||
return (double)vp._length * 1.25 * 0.0625 * 0.46875;
|
||||
case 4:
|
||||
return (double)vp._length * 0.75 * 0.0625 * 0.46875;
|
||||
case 5:
|
||||
return (double)vp._length * 0.67 * 0.0625 * 0.46875;
|
||||
case 6:
|
||||
return (double)vp._length * 0.5 * 0.0625 * 0.46875;
|
||||
default:
|
||||
return (double)vp._length * 1.0 * 0.0625 * 0.46875;
|
||||
}
|
||||
}
|
||||
|
||||
int CMusicRoomHandler::getPitch(MusicInstrument instrument, int arrIndex) {
|
||||
const CMusicSong &song = *_songs[instrument];
|
||||
const CValuePair &vp = song[arrIndex];
|
||||
int val = vp._data;
|
||||
const MusicRoomInstrument &ins1 = _array1[instrument];
|
||||
const MusicRoomInstrument &ins2 = _array2[instrument];
|
||||
|
||||
if (ins1._inversionControl != ins2._inversionControl) {
|
||||
val = song._minVal * 2 + song._range - val;
|
||||
}
|
||||
|
||||
val += ins1._pitchControl + ins2._pitchControl;
|
||||
return val;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
189
engines/titanic/sound/music_room_handler.h
Normal file
189
engines/titanic/sound/music_room_handler.h
Normal file
@@ -0,0 +1,189 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_MUSIC_ROOM_HANDLER_H
|
||||
#define TITANIC_MUSIC_ROOM_HANDLER_H
|
||||
|
||||
#include "titanic/sound/audio_buffer.h"
|
||||
#include "titanic/sound/music_room_instrument.h"
|
||||
#include "titanic/sound/music_song.h"
|
||||
#include "titanic/sound/wave_file.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CProjectItem;
|
||||
class CSoundManager;
|
||||
|
||||
enum MusicInstrument { BELLS = 0, SNAKE = 1, PIANO = 2, BASS = 3 };
|
||||
|
||||
struct MusicRoomInstrument {
|
||||
int _pitchControl;
|
||||
int _speedControl;
|
||||
bool _directionControl;
|
||||
bool _inversionControl;
|
||||
bool _muteControl;
|
||||
MusicRoomInstrument() : _pitchControl(0), _speedControl(0), _directionControl(false),
|
||||
_inversionControl(false), _muteControl(false) {}
|
||||
};
|
||||
|
||||
class CMusicRoomHandler {
|
||||
private:
|
||||
CProjectItem *_project;
|
||||
CSoundManager *_soundManager;
|
||||
CMusicRoomInstrument *_instruments[4];
|
||||
MusicRoomInstrument _array1[4];
|
||||
MusicRoomInstrument _array2[4];
|
||||
CMusicSong *_songs[4];
|
||||
int _startPos[4];
|
||||
int _position[4];
|
||||
double _animExpiryTime[4];
|
||||
|
||||
bool _active;
|
||||
CWaveFile *_waveFile;
|
||||
int _soundHandle;
|
||||
int _instrumentsActive;
|
||||
CAudioBuffer *_audioBuffer;
|
||||
bool _isPlaying;
|
||||
uint _soundStartTicks;
|
||||
uint _startTicks;
|
||||
int _volume;
|
||||
private:
|
||||
/**
|
||||
* Starts music room instruments animation
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* Handles updating the raw audio being played for all the instruments
|
||||
*/
|
||||
void updateAudio();
|
||||
|
||||
/**
|
||||
* Handles updating the instruments themselves, and keeping them animating
|
||||
*/
|
||||
void updateInstruments();
|
||||
|
||||
/**
|
||||
* Polls a specified instrument for any updates to see if it's still active.
|
||||
* @returns Returns true if a given instrument is still active..
|
||||
* that is, that there is still more data that can be read from it to play
|
||||
*/
|
||||
bool pollInstrument(MusicInstrument instrument);
|
||||
|
||||
/**
|
||||
* Gets the duration for a given fragment of an instrument to play
|
||||
* out, so that animations of the instruments can be synchronized
|
||||
* to the actual music
|
||||
*/
|
||||
double getAnimDuration(MusicInstrument instrument, int arrIndex);
|
||||
|
||||
/**
|
||||
* Figures out a pitch value (of some sort) for use in determining
|
||||
* which wave file the music instruments will use.
|
||||
*/
|
||||
int getPitch(MusicInstrument instrument, int arrIndex);
|
||||
public:
|
||||
CMusicRoomHandler(CProjectItem *project, CSoundManager *soundManager);
|
||||
~CMusicRoomHandler();
|
||||
|
||||
/**
|
||||
* Creates a new music room instrument class to handle the operation of one
|
||||
* of the instruments in the music room.
|
||||
* @param instrument Which instrument to create for
|
||||
* @param count Number of Wave files the new instance will contain
|
||||
*/
|
||||
CMusicRoomInstrument *createInstrument(MusicInstrument instrument, int count);
|
||||
|
||||
/**
|
||||
* Main setup for the music room handler
|
||||
*/
|
||||
void setup(int volume);
|
||||
|
||||
/**
|
||||
* Flags whether the music handler is active
|
||||
*/
|
||||
void setActive(bool flag) { _active = flag; }
|
||||
|
||||
/**
|
||||
* Stop playing the music
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* Checks the specified instrument to see if it's settings are "correct"
|
||||
*/
|
||||
bool checkInstrument(MusicInstrument instrument) const;
|
||||
|
||||
/**
|
||||
* Sets the speed control value
|
||||
*/
|
||||
void setSpeedControl2(MusicInstrument instrument, int value);
|
||||
|
||||
/**
|
||||
* Sets the pitch control value
|
||||
*/
|
||||
void setPitchControl2(MusicInstrument instrument, int value);
|
||||
|
||||
/**
|
||||
* Sets the inversion control value
|
||||
*/
|
||||
void setInversionControl2(MusicInstrument instrument, bool value);
|
||||
|
||||
/**
|
||||
* Sets the direction control value
|
||||
*/
|
||||
void setDirectionControl2(MusicInstrument instrument, bool value);
|
||||
|
||||
/**
|
||||
* Sets the pitch control value
|
||||
*/
|
||||
void setPitchControl(MusicInstrument instrument, int value);
|
||||
|
||||
/**
|
||||
* Sets the speed control value
|
||||
*/
|
||||
void setSpeedControl(MusicInstrument instrument, int value);
|
||||
|
||||
/**
|
||||
* Sets the direction control value
|
||||
*/
|
||||
void setDirectionControl(MusicInstrument instrument, bool value);
|
||||
|
||||
/**
|
||||
* Sets the inversion control value
|
||||
*/
|
||||
void setInversionControl(MusicInstrument instrument, bool value);
|
||||
|
||||
/**
|
||||
* Sets the mute control value
|
||||
*/
|
||||
void setMuteControl(MusicInstrument instrument, bool value);
|
||||
|
||||
/**
|
||||
* Handles regular updates
|
||||
* @returns True if the music is still playing
|
||||
*/
|
||||
bool update();
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MUSIC_ROOM_HANDLER_H */
|
||||
355
engines/titanic/sound/music_room_instrument.cpp
Normal file
355
engines/titanic/sound/music_room_instrument.cpp
Normal file
@@ -0,0 +1,355 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/music_room_instrument.h"
|
||||
#include "titanic/sound/sound_manager.h"
|
||||
#include "titanic/core/project_item.h"
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
bool CMusicRoomInstrument::_pianoToggle;
|
||||
int CMusicRoomInstrument::_pianoCtr;
|
||||
int CMusicRoomInstrument::_bassCtr;
|
||||
byte *CMusicRoomInstrument::_buffer;
|
||||
double *CMusicRoomInstrument::_array;
|
||||
int CMusicRoomInstrument::_arrayIndex;
|
||||
|
||||
void CMusicRoomInstrument::init() {
|
||||
_pianoToggle = false;
|
||||
_pianoCtr = 0;
|
||||
_bassCtr = 0;
|
||||
_buffer = nullptr;
|
||||
_array = nullptr;
|
||||
_arrayIndex = 0;
|
||||
}
|
||||
|
||||
void CMusicRoomInstrument::deinit() {
|
||||
delete[] _buffer;
|
||||
delete[] _array;
|
||||
_buffer = nullptr;
|
||||
}
|
||||
|
||||
CMusicRoomInstrument::CMusicRoomInstrument(CProjectItem *project, CSoundManager *soundManager, MusicWaveInstrument instrument) :
|
||||
_project(project), _soundManager(soundManager), _instrument(instrument) {
|
||||
Common::fill(&_gameObjects[0], &_gameObjects[4], (CGameObject *)nullptr);
|
||||
_insStartTime = 0.0;
|
||||
_waveIndex = -1;
|
||||
_readPos = 0;
|
||||
_readIncrement = 0;
|
||||
_size = 0;
|
||||
_count = 0;
|
||||
_field4C = 0;
|
||||
|
||||
switch (instrument) {
|
||||
case MV_PIANO:
|
||||
_gameObjects[0] = static_cast<CGameObject *>(_project->findByName("Piano Man"));
|
||||
_gameObjects[1] = static_cast<CGameObject *>(_project->findByName("Piano Mouth"));
|
||||
_gameObjects[2] = static_cast<CGameObject *>(_project->findByName("Piano Left Arm"));
|
||||
_gameObjects[3] = static_cast<CGameObject *>(_project->findByName("Piano Right Arm"));
|
||||
_insStartTime = 0.45;
|
||||
break;
|
||||
|
||||
case MV_BASS:
|
||||
_gameObjects[0] = static_cast<CGameObject *>(_project->findByName("Bass Player"));
|
||||
break;
|
||||
|
||||
case MV_BELLS:
|
||||
_gameObjects[0] = static_cast<CGameObject *>(_project->findByName("Tubular Bells"));
|
||||
_insStartTime = 0.4;
|
||||
break;
|
||||
|
||||
case MV_SNAKE:
|
||||
_gameObjects[0] = static_cast<CGameObject *>(_project->findByName("Snake_Hammer"));
|
||||
_gameObjects[1] = static_cast<CGameObject *>(_project->findByName("Snake_Glass"));
|
||||
_gameObjects[2] = static_cast<CGameObject *>(_project->findByName("Snake_Head"));
|
||||
_insStartTime = 0.17;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CMusicRoomInstrument::setFilesCount(uint count) {
|
||||
assert(_items.empty());
|
||||
_items.resize(count);
|
||||
}
|
||||
|
||||
void CMusicRoomInstrument::load(int index, const CString &filename, int v3) {
|
||||
assert(!_items[index]._waveFile);
|
||||
_items[index]._waveFile = createWaveFile(filename);
|
||||
_items[index]._value = v3;
|
||||
}
|
||||
|
||||
CWaveFile *CMusicRoomInstrument::createWaveFile(const CString &name) {
|
||||
if (name.empty())
|
||||
return nullptr;
|
||||
return _soundManager->loadSound(name);
|
||||
}
|
||||
|
||||
void CMusicRoomInstrument::start() {
|
||||
if (_gameObjects[0]) {
|
||||
switch (_instrument) {
|
||||
case MV_PIANO:
|
||||
_gameObjects[0]->playMovie(0, 29, MOVIE_STOP_PREVIOUS);
|
||||
_gameObjects[2]->loadFrame(14);
|
||||
_gameObjects[3]->loadFrame(22);
|
||||
break;
|
||||
|
||||
case MV_BELLS:
|
||||
_gameObjects[0]->loadFrame(0);
|
||||
_gameObjects[0]->movieSetPlaying(true);
|
||||
break;
|
||||
|
||||
case MV_SNAKE:
|
||||
_field4C = 22;
|
||||
_gameObjects[1]->playMovie(0, 22, 0);
|
||||
_gameObjects[2]->playMovie(0, 35, MOVIE_STOP_PREVIOUS);
|
||||
_gameObjects[0]->playMovie(0, 1, MOVIE_STOP_PREVIOUS);
|
||||
_gameObjects[0]->playMovie(0, 1, 0);
|
||||
_gameObjects[0]->playMovie(0, 1, 0);
|
||||
_gameObjects[0]->playMovie(0, 1, 0);
|
||||
_gameObjects[0]->playMovie(0, 1, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMusicRoomInstrument::stop() {
|
||||
if (_gameObjects[0]) {
|
||||
switch (_instrument) {
|
||||
case MV_PIANO:
|
||||
_gameObjects[1]->setVisible(false);
|
||||
_gameObjects[2]->setVisible(false);
|
||||
_gameObjects[3]->setVisible(false);
|
||||
_gameObjects[0]->playMovie(29, 58, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
|
||||
case MV_BELLS:
|
||||
_gameObjects[0]->stopMovie();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMusicRoomInstrument::update(int val) {
|
||||
if (_gameObjects[0]) {
|
||||
switch (_instrument) {
|
||||
case MV_PIANO:
|
||||
_gameObjects[1]->setVisible(true);
|
||||
_gameObjects[2]->setVisible(true);
|
||||
_gameObjects[3]->setVisible(true);
|
||||
_gameObjects[_pianoToggle ? 3 : 2]->playMovie(MOVIE_STOP_PREVIOUS);
|
||||
_pianoToggle = !_pianoToggle;
|
||||
|
||||
switch (_pianoCtr) {
|
||||
case 0:
|
||||
_gameObjects[1]->playMovie(0, 4, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
case 1:
|
||||
_gameObjects[1]->playMovie(4, 8, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
case 2:
|
||||
_gameObjects[1]->playMovie(8, 12, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
case 3:
|
||||
_gameObjects[1]->playMovie(12, 16, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_pianoCtr = (_pianoCtr + 1) % 4;
|
||||
break;
|
||||
|
||||
case MV_BASS:
|
||||
switch (_bassCtr) {
|
||||
case 0:
|
||||
_gameObjects[0]->playMovie(0, 7, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
case 1:
|
||||
_gameObjects[0]->playMovie(7, 14, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
case 2:
|
||||
_gameObjects[0]->playMovie(15, 24, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
case 3:
|
||||
_gameObjects[0]->playMovie(25, 33, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// WORKAROUND: Original didn't change the selected bass animation
|
||||
_bassCtr = (_bassCtr + 1) % 4;
|
||||
break;
|
||||
|
||||
case MV_BELLS:
|
||||
switch (val) {
|
||||
case 60:
|
||||
_gameObjects[0]->playMovie(0, 512, MOVIE_STOP_PREVIOUS);
|
||||
_gameObjects[0]->movieSetPlaying(true);
|
||||
_insStartTime = 0.6;
|
||||
break;
|
||||
|
||||
case 62:
|
||||
_gameObjects[0]->playMovie(828, 1023, MOVIE_STOP_PREVIOUS);
|
||||
_insStartTime = 0.3;
|
||||
break;
|
||||
|
||||
case 63:
|
||||
_gameObjects[0]->playMovie(1024, 1085, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MV_SNAKE: {
|
||||
_gameObjects[0]->playMovie(0, 7, MOVIE_STOP_PREVIOUS);
|
||||
|
||||
double tempVal = 46.0 - ((double)(val - 14) * 1.43);
|
||||
int frameNum = _field4C;
|
||||
int frameNum1 = (int)((tempVal - frameNum) * 0.25);
|
||||
_gameObjects[1]->playMovie(frameNum1, frameNum1, MOVIE_STOP_PREVIOUS);
|
||||
|
||||
frameNum += frameNum1;
|
||||
_gameObjects[1]->playMovie(frameNum, frameNum, 0);
|
||||
|
||||
frameNum += frameNum1;
|
||||
_gameObjects[1]->playMovie(frameNum, frameNum, 0);
|
||||
|
||||
_gameObjects[2]->playMovie(45, 49, MOVIE_STOP_PREVIOUS);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CMusicRoomInstrument::clear() {
|
||||
_waveIndex = 0;
|
||||
_readPos = 0;
|
||||
_readIncrement = 0;
|
||||
_size = 0;
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
void CMusicRoomInstrument::reset(uint total) {
|
||||
_waveIndex = -1;
|
||||
_readPos = 0;
|
||||
_readIncrement = 0;
|
||||
_size = total;
|
||||
_count = 0;
|
||||
}
|
||||
|
||||
int CMusicRoomInstrument::read(int16 *ptr, uint size) {
|
||||
if (!_size)
|
||||
return 0;
|
||||
|
||||
if (size >= _size)
|
||||
size = _size;
|
||||
|
||||
if (_waveIndex != -1) {
|
||||
// Lock the specified wave file for access
|
||||
const int16 *data = _items[_waveIndex]._waveFile->lock();
|
||||
assert(data);
|
||||
const int16 *src = data;
|
||||
|
||||
// Loop through merging data from the wave file into the dest buffer
|
||||
for (uint idx = 0; idx < (size / sizeof(int16)); ++idx, _readPos += _readIncrement) {
|
||||
uint srcPos = _readPos >> 8;
|
||||
if (srcPos >= _count)
|
||||
break;
|
||||
|
||||
int16 val = READ_LE_UINT16(src + srcPos);
|
||||
*ptr++ += val;
|
||||
}
|
||||
|
||||
// Unlock the wave file
|
||||
_items[_waveIndex]._waveFile->unlock(data);
|
||||
}
|
||||
|
||||
_size -= size;
|
||||
return size;
|
||||
}
|
||||
|
||||
void CMusicRoomInstrument::chooseWaveFile(int index, int size) {
|
||||
if (!_array)
|
||||
setupArray(-36, 36);
|
||||
|
||||
int minDiff = ABS(_items[0]._value - index);
|
||||
int waveIndex = 0;
|
||||
|
||||
for (uint idx = 1; idx < _items.size(); ++idx) {
|
||||
int diff = ABS(_items[idx]._value - index);
|
||||
if (diff < minDiff) {
|
||||
minDiff = diff;
|
||||
waveIndex = idx;
|
||||
}
|
||||
}
|
||||
|
||||
const CInstrumentWaveFile &wf = _items[waveIndex];
|
||||
int arrIndex = _arrayIndex - wf._value + index;
|
||||
uint waveSize = wf._waveFile->size();
|
||||
|
||||
_waveIndex = waveIndex;
|
||||
_readPos = 0;
|
||||
_readIncrement = (int)(_array[arrIndex] * 256);
|
||||
_size = size;
|
||||
_count = waveSize / 2;
|
||||
}
|
||||
|
||||
void CMusicRoomInstrument::setupArray(int minVal, int maxVal) {
|
||||
// Delete any prior array and recreate it
|
||||
delete[] _array;
|
||||
|
||||
int arrSize = maxVal - minVal + 1;
|
||||
_array = new double[arrSize];
|
||||
_arrayIndex = ABS(minVal);
|
||||
|
||||
// Setup array contents
|
||||
_array[_arrayIndex] = 1.0;
|
||||
|
||||
double val = 1.0594634;
|
||||
for (int idx = 1; idx <= maxVal; ++idx) {
|
||||
_array[_arrayIndex + idx] = val;
|
||||
val *= 1.0594634;
|
||||
}
|
||||
|
||||
val = 0.94387404038686;
|
||||
for (int idx = -1; idx >= minVal; --idx) {
|
||||
_array[_arrayIndex + idx] = val;
|
||||
val *= 0.94387404038686;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
141
engines/titanic/sound/music_room_instrument.h
Normal file
141
engines/titanic/sound/music_room_instrument.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_MUSIC_ROOM_INSTRUMENT_H
|
||||
#define TITANIC_MUSIC_ROOM_INSTRUMENT_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "titanic/support/string.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum MusicWaveInstrument { MV_PIANO = 0, MV_BASS = 1, MV_BELLS = 2, MV_SNAKE = 3 };
|
||||
|
||||
class CProjectItem;
|
||||
class CSoundManager;
|
||||
class CWaveFile;
|
||||
class CGameObject;
|
||||
|
||||
class CMusicRoomInstrument {
|
||||
struct CInstrumentWaveFile {
|
||||
CWaveFile *_waveFile;
|
||||
int _value;
|
||||
CInstrumentWaveFile() : _waveFile(nullptr), _value(0) {}
|
||||
};
|
||||
private:
|
||||
static bool _pianoToggle;
|
||||
static int _pianoCtr;
|
||||
static int _bassCtr;
|
||||
static byte *_buffer;
|
||||
static double *_array;
|
||||
static int _arrayIndex;
|
||||
private:
|
||||
CSoundManager *_soundManager;
|
||||
Common::Array<CInstrumentWaveFile> _items;
|
||||
MusicWaveInstrument _instrument;
|
||||
CProjectItem *_project;
|
||||
CGameObject *_gameObjects[4];
|
||||
int _waveIndex;
|
||||
int _readPos;
|
||||
int _readIncrement;
|
||||
uint _size;
|
||||
uint _count;
|
||||
int _field4C;
|
||||
private:
|
||||
/**
|
||||
* Loads the specified wave file, and returns a CWaveFile instance for it
|
||||
*/
|
||||
CWaveFile *createWaveFile(const CString &name);
|
||||
|
||||
/**
|
||||
* Sets up an array used for figuring out the sequence in which to
|
||||
* play the different wave files for each instrument to give the
|
||||
* music based on the console's settings
|
||||
*/
|
||||
void setupArray(int minVal, int maxVal);
|
||||
public:
|
||||
double _insStartTime;
|
||||
public:
|
||||
/**
|
||||
* Handles initialization of static fields
|
||||
*/
|
||||
static void init();
|
||||
|
||||
/**
|
||||
* Deinitialization of static fields
|
||||
*/
|
||||
static void deinit();
|
||||
public:
|
||||
CMusicRoomInstrument(CProjectItem *project, CSoundManager *soundManager, MusicWaveInstrument instrument);
|
||||
|
||||
/**
|
||||
* Sets the maximum number of allowed files that be defined
|
||||
*/
|
||||
void setFilesCount(uint count);
|
||||
|
||||
/**
|
||||
* Loads a new file into the list of available entries
|
||||
*/
|
||||
void load(int index, const CString &filename, int v3);
|
||||
|
||||
|
||||
/**
|
||||
* Starts the music and associated animations
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* Stops the music and associated animations
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* Handles regular updates of the instrument, allowing associated
|
||||
* objects to start animations as the music is played
|
||||
*/
|
||||
void update(int val);
|
||||
|
||||
/**
|
||||
* Clear the instrument
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Resets the instrument, and sets the maximum for how much data can
|
||||
* be read from the wave files during each read action
|
||||
*/
|
||||
void reset(uint total);
|
||||
|
||||
/**
|
||||
* If there is any wave file currently specified, reads it in
|
||||
* and merges it into the supplied buffer
|
||||
*/
|
||||
int read(int16 *ptr, uint size);
|
||||
|
||||
/**
|
||||
* Figure out which wave file to use next
|
||||
*/
|
||||
void chooseWaveFile(int index, int freq);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MUSIC_ROOM_INSTRUMENT_H */
|
||||
192
engines/titanic/sound/music_song.cpp
Normal file
192
engines/titanic/sound/music_song.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/music_song.h"
|
||||
#include "titanic/support/files_manager.h"
|
||||
#include "titanic/titanic.h"
|
||||
#include "common/util.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CMusicSong::CMusicSong(int index) {
|
||||
// Read in the list of song strings
|
||||
Common::SeekableReadStream *res = g_vm->_filesManager->getResource("MUSIC/PARSER");
|
||||
Common::StringArray parserStrings;
|
||||
while (res->pos() < res->size())
|
||||
parserStrings.push_back(readStringFromStream(res));
|
||||
delete res;
|
||||
|
||||
// Set up a new song parser with the desired string
|
||||
CSongParser parser(parserStrings[index].c_str());
|
||||
|
||||
// Count how many encoded values there are
|
||||
CValuePair r;
|
||||
int count = 0;
|
||||
while (parser.parse(r))
|
||||
++count;
|
||||
assert(count > 0);
|
||||
|
||||
// Read in the values to the array
|
||||
_data.resize(count);
|
||||
parser.reset();
|
||||
for (int idx = 0; idx < count; ++idx)
|
||||
parser.parse(_data[idx]);
|
||||
|
||||
// Figure out the range of values in the array
|
||||
_minVal = 0x7FFFFFFF;
|
||||
int maxVal = -0x7FFFFFFF;
|
||||
|
||||
for (int idx = 0; idx < count; ++idx) {
|
||||
CValuePair &vp = _data[idx];
|
||||
if (vp._data != 0x7FFFFFFF) {
|
||||
if (vp._data < _minVal)
|
||||
_minVal = vp._data;
|
||||
if (vp._data > maxVal)
|
||||
maxVal = vp._data;
|
||||
}
|
||||
}
|
||||
|
||||
_range = maxVal - _minVal;
|
||||
}
|
||||
|
||||
CMusicSong::~CMusicSong() {
|
||||
_data.clear();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
#define FETCH_CHAR _currentChar = _str[_strIndex++]
|
||||
|
||||
CSongParser::CSongParser(const char *str) : _str(str), _strIndex(0),
|
||||
_field8(0), _priorChar('A'), _field10(32), _field14(0), _flag(false),
|
||||
_field1C(0), _currentChar(' '), _numValue(1) {
|
||||
}
|
||||
|
||||
void CSongParser::reset() {
|
||||
_strIndex = 0;
|
||||
_field8 = 0;
|
||||
_field10 = 0;
|
||||
_field14 = 0;
|
||||
_currentChar = ' ';
|
||||
_priorChar = 'A';
|
||||
_numValue = 1;
|
||||
_field1C = 0;
|
||||
}
|
||||
|
||||
bool CSongParser::parse(CValuePair &r) {
|
||||
const int INDEXES[8] = { 0, 2, 3, 5, 7, 8, 10, 0 };
|
||||
|
||||
while (_currentChar) {
|
||||
skipSpaces();
|
||||
|
||||
if (Common::isDigit(_currentChar)) {
|
||||
// Parse the number
|
||||
Common::String numStr;
|
||||
do {
|
||||
numStr += _currentChar;
|
||||
FETCH_CHAR;
|
||||
} while (_currentChar && Common::isDigit(_currentChar));
|
||||
|
||||
_numValue = atoi(numStr.c_str());
|
||||
} else if (_currentChar == ',') {
|
||||
_field10 = _numValue;
|
||||
FETCH_CHAR;
|
||||
} else if (_currentChar == ':') {
|
||||
_priorChar = 'A';
|
||||
_field8 = _numValue * 12;
|
||||
FETCH_CHAR;
|
||||
} else if (_currentChar == '/') {
|
||||
r._length += _field10;
|
||||
_field1C += _field10;
|
||||
FETCH_CHAR;
|
||||
} else if (_currentChar == '+') {
|
||||
++_field14;
|
||||
FETCH_CHAR;
|
||||
} else if (_currentChar == '-') {
|
||||
--_field14;
|
||||
FETCH_CHAR;
|
||||
} else if (_currentChar == '^') {
|
||||
if (_flag)
|
||||
break;
|
||||
|
||||
_flag = true;
|
||||
r._data = 0x7FFFFFFF;
|
||||
r._length = _field10;
|
||||
_field14 = 0;
|
||||
_field1C += _field10;
|
||||
FETCH_CHAR;
|
||||
} else if (_currentChar == '|') {
|
||||
_field1C = 0;
|
||||
FETCH_CHAR;
|
||||
} else if (Common::isAlpha(_currentChar)) {
|
||||
if (_flag)
|
||||
break;
|
||||
|
||||
int val1 = INDEXES[tolower(_currentChar) - 'a'];
|
||||
int val2 = INDEXES[tolower(_priorChar) - 'a'];
|
||||
bool flag = true;
|
||||
|
||||
if (_currentChar == _priorChar) {
|
||||
r._data = _field8;
|
||||
} else if (_currentChar >= 'a' && _currentChar <= 'g') {
|
||||
val1 -= val2;
|
||||
if (val1 >= 0)
|
||||
val1 -= 12;
|
||||
r._data = _field8 + val1;
|
||||
} else if (_currentChar >= 'A' && _currentChar <= 'G') {
|
||||
val1 -= val2;
|
||||
if (val1 <= 0)
|
||||
val1 += 12;
|
||||
r._data = _field8 + val1;
|
||||
} else {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
r._length = _field10;
|
||||
_field1C += _field10;
|
||||
_field8 = r._data;
|
||||
_priorChar = _currentChar;
|
||||
r._data += _field14;
|
||||
_field14 = 0;
|
||||
_flag = true;
|
||||
}
|
||||
|
||||
FETCH_CHAR;
|
||||
} else {
|
||||
FETCH_CHAR;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_flag)
|
||||
return false;
|
||||
|
||||
_flag = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CSongParser::skipSpaces() {
|
||||
while (_currentChar && Common::isSpace(_currentChar)) {
|
||||
FETCH_CHAR;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
80
engines/titanic/sound/music_song.h
Normal file
80
engines/titanic/sound/music_song.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_MUSIC_SONG_H
|
||||
#define TITANIC_MUSIC_SONG_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/array.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
struct CValuePair {
|
||||
int _data;
|
||||
int _length;
|
||||
CValuePair() : _data(0), _length(0) {}
|
||||
};
|
||||
|
||||
class CMusicSong {
|
||||
public:
|
||||
Common::Array<CValuePair> _data;
|
||||
int _minVal;
|
||||
int _range;
|
||||
public:
|
||||
CMusicSong(int index);
|
||||
~CMusicSong();
|
||||
|
||||
int size() const { return _data.size(); }
|
||||
|
||||
const CValuePair &operator[](int index) const { return _data[index]; }
|
||||
};
|
||||
|
||||
class CSongParser {
|
||||
private:
|
||||
const char *_str;
|
||||
uint _strIndex;
|
||||
int _field8;
|
||||
char _priorChar;
|
||||
int _field10;
|
||||
int _field14;
|
||||
bool _flag;
|
||||
int _field1C;
|
||||
char _currentChar;
|
||||
int _numValue;
|
||||
private:
|
||||
void skipSpaces();
|
||||
public:
|
||||
CSongParser(const char *str);
|
||||
|
||||
/**
|
||||
* Resets the parser
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Parses a value from the string
|
||||
*/
|
||||
bool parse(CValuePair &r);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_MUSIC_SONG_H */
|
||||
83
engines/titanic/sound/node_auto_sound_player.cpp
Normal file
83
engines/titanic/sound/node_auto_sound_player.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/node_auto_sound_player.h"
|
||||
#include "titanic/sound/auto_music_player.h"
|
||||
#include "titanic/core/room_item.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CNodeAutoSoundPlayer, CAutoSoundPlayer)
|
||||
ON_MESSAGE(EnterNodeMsg)
|
||||
ON_MESSAGE(LeaveNodeMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CNodeAutoSoundPlayer::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_enabled, indent);
|
||||
CAutoSoundPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CNodeAutoSoundPlayer::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_enabled = file->readNumber();
|
||||
CAutoSoundPlayer::load(file);
|
||||
}
|
||||
|
||||
bool CNodeAutoSoundPlayer::EnterNodeMsg(CEnterNodeMsg *msg) {
|
||||
CNodeItem *node = findNode();
|
||||
CRoomItem *room = findRoom();
|
||||
|
||||
if (node == msg->_newNode) {
|
||||
CTurnOn onMsg;
|
||||
onMsg.execute(this);
|
||||
|
||||
if (_enabled) {
|
||||
CChangeMusicMsg changeMsg;
|
||||
changeMsg._action = MUSIC_STOP;
|
||||
changeMsg.execute(room, CAutoMusicPlayer::_type,
|
||||
MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CNodeAutoSoundPlayer::LeaveNodeMsg(CLeaveNodeMsg *msg) {
|
||||
CNodeItem *node = findNode();
|
||||
CRoomItem *room = findRoom();
|
||||
|
||||
if (node == msg->_oldNode) {
|
||||
CTurnOff offMsg;
|
||||
offMsg.execute(this);
|
||||
|
||||
if (_enabled) {
|
||||
CChangeMusicMsg changeMsg;
|
||||
changeMsg._action = MUSIC_START;
|
||||
changeMsg.execute(room, CAutoMusicPlayer::_type,
|
||||
MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
53
engines/titanic/sound/node_auto_sound_player.h
Normal file
53
engines/titanic/sound/node_auto_sound_player.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_NODE_AUTO_SOUND_PLAYER_H
|
||||
#define TITANIC_NODE_AUTO_SOUND_PLAYER_H
|
||||
|
||||
#include "titanic/sound/auto_sound_player.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CNodeAutoSoundPlayer : public CAutoSoundPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool EnterNodeMsg(CEnterNodeMsg *msg);
|
||||
bool LeaveNodeMsg(CLeaveNodeMsg *msg);
|
||||
private:
|
||||
bool _enabled;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CNodeAutoSoundPlayer() : CAutoSoundPlayer(), _enabled(true) {}
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_NODE_AUTO_SOUND_PLAYER_H */
|
||||
47
engines/titanic/sound/proximity.cpp
Normal file
47
engines/titanic/sound/proximity.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/proximity.h"
|
||||
#include "titanic/true_talk/tt_talker.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CProximity::CProximity() : _channelVolume(100), _balance(0),
|
||||
_priorSoundHandle(-1), _frequencyMultiplier(0.0), _frequencyAdjust(1.875),
|
||||
_repeated(false), _channelMode(10), _positioningMode(POSMODE_NONE),
|
||||
_azimuth(0.0), _range(0.5), _elevation(0),
|
||||
_posX(0.0), _posY(0.0), _posZ(0.0),
|
||||
_hasVelocity(false), _velocityX(0), _velocityY(0), _velocityZ(0),
|
||||
_disposeAfterUse(DisposeAfterUse::NO), _endTalkerFn(nullptr), _talker(nullptr),
|
||||
_soundDuration(0), _soundType(Audio::Mixer::kPlainSoundType) {
|
||||
}
|
||||
|
||||
CProximity::CProximity(Audio::Mixer::SoundType soundType, int volume) :
|
||||
_soundType(soundType), _channelVolume(volume),
|
||||
_balance(0), _priorSoundHandle(-1), _frequencyMultiplier(0.0),
|
||||
_frequencyAdjust(1.875), _repeated(false), _channelMode(10),
|
||||
_positioningMode(POSMODE_NONE), _azimuth(0.0), _range(0.5), _elevation(0),
|
||||
_posX(0.0), _posY(0.0), _posZ(0.0), _hasVelocity(false), _velocityX(0),
|
||||
_velocityY(0), _velocityZ(0), _disposeAfterUse(DisposeAfterUse::NO),
|
||||
_endTalkerFn(nullptr), _talker(nullptr), _soundDuration(0) {
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
68
engines/titanic/sound/proximity.h
Normal file
68
engines/titanic/sound/proximity.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_PROXIMITY_H
|
||||
#define TITANIC_PROXIMITY_H
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "common/scummsys.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum PositioningMode { POSMODE_NONE = 0, POSMODE_POLAR = 1, POSMODE_VECTOR = 2 };
|
||||
|
||||
class TTtalker;
|
||||
|
||||
typedef void (*CEndTalkerFn)(TTtalker *talker);
|
||||
|
||||
class CProximity {
|
||||
public:
|
||||
int _channelVolume;
|
||||
int _balance;
|
||||
int _priorSoundHandle;
|
||||
double _frequencyMultiplier;
|
||||
double _frequencyAdjust;
|
||||
bool _repeated;
|
||||
int _channelMode;
|
||||
PositioningMode _positioningMode;
|
||||
double _azimuth;
|
||||
double _range;
|
||||
double _elevation;
|
||||
double _posX;
|
||||
double _posY;
|
||||
double _posZ;
|
||||
bool _hasVelocity;
|
||||
double _velocityX;
|
||||
double _velocityY;
|
||||
double _velocityZ;
|
||||
DisposeAfterUse::Flag _disposeAfterUse;
|
||||
CEndTalkerFn _endTalkerFn;
|
||||
TTtalker *_talker;
|
||||
uint _soundDuration;
|
||||
Audio::Mixer::SoundType _soundType;
|
||||
public:
|
||||
CProximity();
|
||||
CProximity(Audio::Mixer::SoundType soundType, int volume = 100);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_PROXIMITY_H */
|
||||
254
engines/titanic/sound/qmixer.cpp
Normal file
254
engines/titanic/sound/qmixer.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/qmixer.h"
|
||||
#include "titanic/debugger.h"
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
QMixer::QMixer(Audio::Mixer *mixer) : _mixer(mixer) {
|
||||
}
|
||||
|
||||
QMixer::~QMixer() {
|
||||
_channels.clear();
|
||||
}
|
||||
|
||||
bool QMixer::qsWaveMixInitEx(const QMIXCONFIG &config) {
|
||||
assert(_channels.empty());
|
||||
assert(config.iChannels > 0 && config.iChannels < 256);
|
||||
|
||||
_channels.resize(config.iChannels);
|
||||
return true;
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixActivate(bool fActivate) {
|
||||
// Not currently implemented in ScummVM
|
||||
}
|
||||
|
||||
int QMixer::qsWaveMixOpenChannel(int iChannel, QMixFlag mode) {
|
||||
// Not currently implemented in ScummVM
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QMixer::qsWaveMixEnableChannel(int iChannel, uint flags, bool enabled) {
|
||||
// Not currently implemented in ScummVM
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixCloseSession() {
|
||||
_mixer->stopAll();
|
||||
_channels.clear();
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixFreeWave(Audio::SoundHandle &handle) {
|
||||
_mixer->stopHandle(handle);
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixFlushChannel(int iChannel, uint flags) {
|
||||
if (flags & QMIX_OPENALL) {
|
||||
// Ignore channel, and flush all the channels
|
||||
for (uint idx = 0; idx < _channels.size(); ++idx)
|
||||
qsWaveMixFlushChannel(idx, 0);
|
||||
} else {
|
||||
// Flush the specified channel
|
||||
Common::List<SoundEntry>::iterator i;
|
||||
Common::List<SoundEntry> &sounds = _channels[iChannel]._sounds;
|
||||
for (i = sounds.begin(); i != sounds.end(); ++i)
|
||||
_mixer->stopHandle((*i)._soundHandle);
|
||||
|
||||
sounds.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixSetPanRate(int iChannel, uint flags, uint rate) {
|
||||
ChannelEntry &channel = _channels[iChannel];
|
||||
channel._panRate = rate;
|
||||
channel._volumeChangeStart = channel._volumeChangeEnd = 0;
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixSetVolume(int iChannel, uint flags, uint volume) {
|
||||
ChannelEntry &channel = _channels[iChannel];
|
||||
|
||||
// QMixer volumes go from 0-32767, but we need to convert to 0-255 for ScummVM
|
||||
assert(volume <= 32767);
|
||||
byte newVolume = (volume >= 32700) ? 255 : volume * 255 / 32767;
|
||||
|
||||
channel._volumeStart = channel._volume;
|
||||
channel._volumeEnd = newVolume;
|
||||
channel._volumeChangeStart = g_system->getMillis();
|
||||
channel._volumeChangeEnd = channel._volumeChangeStart + channel._panRate;
|
||||
debugC(DEBUG_DETAILED, kDebugCore, "qsWaveMixSetPanRate vol=%d to %d, start=%u, end=%u",
|
||||
channel._volumeStart, channel._volumeEnd, channel._volumeChangeStart, channel._volumeChangeEnd);
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixSetSourcePosition(int iChannel, uint flags, const QSVECTOR &position) {
|
||||
ChannelEntry &channel = _channels[iChannel];
|
||||
|
||||
// Flag whether distance should reset when a new sound is started
|
||||
channel._resetDistance = (flags & QMIX_USEONCE) != 0;
|
||||
|
||||
// Currently, we only do a basic simulation of spatial positioning by
|
||||
// getting the distance, and proportionately reducing the volume the
|
||||
// further away the source is
|
||||
channel._distance = sqrt(position.x * position.x + position.y * position.y
|
||||
+ position.z * position.z);
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixSetPolarPosition(int iChannel, uint flags, const QSPOLAR &position) {
|
||||
ChannelEntry &channel = _channels[iChannel];
|
||||
|
||||
// Flag whether distance should reset when a new sound is started
|
||||
channel._resetDistance = (flags & QMIX_USEONCE) != 0;
|
||||
|
||||
// Currently, we only do a basic simulation of spatial positioning by
|
||||
// getting the distance, and proportionately reducing the volume the
|
||||
// further away the source is
|
||||
channel._distance = position.range;
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixSetListenerPosition(const QSVECTOR &position, uint flags) {
|
||||
// Not currently implemented in ScummVM
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixSetListenerOrientation(const QSVECTOR &direction, const QSVECTOR &up, uint flags) {
|
||||
// Not currently implemented in ScummVM
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixSetDistanceMapping(int iChannel, uint flags, const QMIX_DISTANCES &distances) {
|
||||
// Not currently implemented in ScummVM
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixSetFrequency(int iChannel, uint flags, uint frequency) {
|
||||
// Not currently implemented in ScummVM
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixSetSourceVelocity(int iChannel, uint flags, const QSVECTOR &velocity) {
|
||||
// Not currently implemented in ScummVM
|
||||
}
|
||||
|
||||
int QMixer::qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *waveFile, int loops, const QMIXPLAYPARAMS ¶ms) {
|
||||
if (iChannel == -1) {
|
||||
// Find a free channel
|
||||
for (iChannel = 0; iChannel < (int)_channels.size(); ++iChannel) {
|
||||
if (_channels[iChannel]._sounds.empty())
|
||||
break;
|
||||
}
|
||||
assert(iChannel != (int)_channels.size());
|
||||
}
|
||||
|
||||
// If the new sound replaces current ones, then clear the channel
|
||||
ChannelEntry &channel = _channels[iChannel];
|
||||
if (flags & QMIX_CLEARQUEUE) {
|
||||
if (!channel._sounds.empty() && channel._sounds.front()._started)
|
||||
_mixer->stopHandle(channel._sounds.front()._soundHandle);
|
||||
|
||||
channel._sounds.clear();
|
||||
}
|
||||
|
||||
// Add the sound to the channel
|
||||
channel._sounds.push_back(SoundEntry(waveFile, params.callback, loops, params.dwUser));
|
||||
qsWaveMixPump();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool QMixer::qsWaveMixIsChannelDone(int iChannel) const {
|
||||
return _channels[iChannel]._sounds.empty();
|
||||
}
|
||||
|
||||
void QMixer::qsWaveMixPump() {
|
||||
// Iterate through each of the channels
|
||||
for (uint iChannel = 0; iChannel < _channels.size(); ++iChannel) {
|
||||
ChannelEntry &channel = _channels[iChannel];
|
||||
|
||||
// If there's a transition in sound volume in progress, handle it
|
||||
if (channel._volumeChangeEnd) {
|
||||
byte oldVolume = channel._volume;
|
||||
uint currentTicks = g_system->getMillis();
|
||||
|
||||
if (currentTicks >= channel._volumeChangeEnd) {
|
||||
// Reached end of transition period
|
||||
channel._volume = channel._volumeEnd;
|
||||
channel._volumeChangeStart = channel._volumeChangeEnd = 0;
|
||||
} else {
|
||||
// Transition in progress, so figure out new volume
|
||||
channel._volume = (int)channel._volumeStart +
|
||||
((int)channel._volumeEnd - (int)channel._volumeStart) *
|
||||
(int)(currentTicks - channel._volumeChangeStart) / (int)channel._panRate;
|
||||
}
|
||||
|
||||
debugC(DEBUG_DETAILED, kDebugCore, "qsWaveMixPump time=%u vol=%d",
|
||||
currentTicks, channel._volume);
|
||||
|
||||
if (channel._volume != oldVolume && !channel._sounds.empty()
|
||||
&& channel._sounds.front()._started) {
|
||||
_mixer->setChannelVolume(channel._sounds.front()._soundHandle,
|
||||
channel.getRawVolume());
|
||||
}
|
||||
}
|
||||
|
||||
// If the playing sound on the channel is finished, then call
|
||||
// the callback registered for it, and remove it from the list
|
||||
if (!channel._sounds.empty()) {
|
||||
SoundEntry &sound = channel._sounds.front();
|
||||
if (sound._started && !_mixer->isSoundHandleActive(sound._soundHandle)) {
|
||||
// Sound is finished
|
||||
if (sound._callback)
|
||||
// Call the callback to signal end
|
||||
sound._callback(iChannel, sound._waveFile, sound._userData);
|
||||
|
||||
// Remove sound record from channel
|
||||
channel._sounds.erase(channel._sounds.begin());
|
||||
}
|
||||
}
|
||||
|
||||
// If there's an unstarted sound at the front of a channel's
|
||||
// sound list, then start it playing
|
||||
if (!channel._sounds.empty()) {
|
||||
SoundEntry &sound = channel._sounds.front();
|
||||
if (!sound._started) {
|
||||
if (channel._resetDistance)
|
||||
channel._distance = 0.0;
|
||||
|
||||
// Play the wave
|
||||
sound._soundHandle = sound._waveFile->play(
|
||||
sound._loops, channel.getRawVolume());
|
||||
sound._started = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
byte QMixer::ChannelEntry::getRawVolume() const {
|
||||
// Emperically decided adjustment divisor for distances
|
||||
const double ADJUSTMENT_FACTOR = 5.0;
|
||||
|
||||
double r = 1.0 + (_distance / ADJUSTMENT_FACTOR);
|
||||
double percent = 1.0 / (r * r);
|
||||
|
||||
double newVolume = _volume * percent;
|
||||
return (byte)newVolume;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
335
engines/titanic/sound/qmixer.h
Normal file
335
engines/titanic/sound/qmixer.h
Normal file
@@ -0,0 +1,335 @@
|
||||
/* 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 3 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
|
||||
* aint with this program; if not, write to the Free Software
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_QMIXER_H
|
||||
#define TITANIC_QMIXER_H
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "titanic/sound/wave_file.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum QMixFlag {
|
||||
QMIX_OPENSINGLE = 0, // Open the single channel specified by iChannel
|
||||
QMIX_OPENALL = 1, // Opens all the channels, iChannel ignored
|
||||
QMIX_OPENCOUNT = 2, // Open iChannel Channels (eg. if iChannel = 4 will create channels 0-3)
|
||||
QMIX_OPENAVAILABLE = 3, // Open the first unopened channel, and return channel number
|
||||
|
||||
// Channel function flags
|
||||
QMIX_ALL = 0x01, // apply to all channels
|
||||
QMIX_NOREMIX = 0x02, // don't remix
|
||||
QMIX_CONTROL_NOREMIX = 0x04, // don't remix
|
||||
QMIX_USEONCE = 0x10 // settings are temporary
|
||||
};
|
||||
|
||||
// qsWaveMixEnableChannel flags: if mode==0, use conventional, high-performance
|
||||
// stereo mixer. Non-zero modes imply some form of additional processing.
|
||||
enum QMixChannelFlag {
|
||||
QMIX_CHANNEL_STEREO = 0x0000, // Perform stereo mixing
|
||||
QMIX_CHANNEL_QSOUND = 0x0001, // Perform QSound localization (default)
|
||||
QMIX_CHANNEL_DOPPLER = 0x0002, // Calculate velocity using position updates
|
||||
QMIX_CHANNEL_RANGE = 0x0004, // Do range effects
|
||||
QMIX_CHANNEL_ELEVATION = 0x0008, // Do elevation effects
|
||||
QMIX_CHANNEL_NODOPPLERPITCH = 0x0010, // Disable Doppler pitch shift for this channel
|
||||
QMIX_CHANNEL_PITCH_COPY = 0x0000, // Pitch shifting using copying (fastest)
|
||||
QMIX_CHANNEL_PITCH_LINEAR = 0x0100, // Pitch shifting using linear interpolation (better but slower)
|
||||
QMIX_CHANNEL_PITCH_SPLINE = 0x0200, // Pitch shifting using spline interpolation (better yet, but much slower)
|
||||
QMIX_CHANNEL_PITCH_FILTER = 0x0300, // Pitch shifting using FIR filter (best, but slowest)
|
||||
QMIX_CHANNEL_PITCH_MASK = 0x0700 // Bits reserved for pitch types
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for dwFlags parameter in QSWaveMixPlayEx.
|
||||
*
|
||||
* Notes: The QMIX_USELRUCHANNEL flag has two roles. When QMIX_CLEARQUEUE is also set,
|
||||
* the channel that has been playing the longest (least-recently-used) is cleared and
|
||||
* the buffer played. When QMIX_QUEUEWAVE is set, the channel that will first finish
|
||||
* playing will be selected and the buffer queued to play. Of course, if an unused
|
||||
* channel is found, it will be selected instead.
|
||||
* If QMIX_WAIT hasn't been specified, then the channel number will be returned
|
||||
* in the iChannel field.
|
||||
*/
|
||||
enum QMixPlayFlag {
|
||||
QMIX_QUEUEWAVE = 0x0000, // Queue on channel
|
||||
QMIX_CLEARQUEUE = 0x0001, // Clear queue on channel
|
||||
QMIX_USELRUCHANNEL = 0x0002, // See notes above
|
||||
QMIX_HIGHPRIORITY = 0x0004,
|
||||
QMIX_WAIT = 0x0008, // Queue to be played with other sounds
|
||||
QMIX_IMMEDIATE = 0x0020, // Apply volume/pan changes without interpolation
|
||||
|
||||
QMIX_PLAY_SETEVENT = 0x0100, // Calls SetEvent in the original library when done
|
||||
QMIX_PLAY_PULSEEVENT = 0x0200, // Calls PulseEvent in the original library when done
|
||||
QMIX_PLAY_NOTIFYSTOP = 0x0400 // Do callback even when stopping or flushing sound
|
||||
};
|
||||
|
||||
/**
|
||||
* Mixer configuration structure for qsWaveMixInitEx
|
||||
*/
|
||||
struct QMIXCONFIG {
|
||||
uint32 dwSize;
|
||||
uint32 dwFlags;
|
||||
uint32 dwSamplingRate; // Sampling rate in Hz
|
||||
void *lpIDirectSound;
|
||||
const void *lpGuid;
|
||||
int iChannels; // Number of channels
|
||||
int iOutput; // if 0, uses best output device
|
||||
int iLatency; // (in ms) if 0, uses default for output device
|
||||
int iMath; // style of math
|
||||
uint hwnd;
|
||||
|
||||
QMIXCONFIG() : dwSize(40), dwFlags(0), dwSamplingRate(0), lpIDirectSound(nullptr),
|
||||
lpGuid(nullptr), iChannels(0), iOutput(0), iLatency(0), iMath(0), hwnd(0) {}
|
||||
QMIXCONFIG(uint32 rate, int channels, int latency) : dwSize(40), dwFlags(0),
|
||||
dwSamplingRate(rate), iChannels(channels), iLatency(latency),
|
||||
lpIDirectSound(nullptr), lpGuid(nullptr), iOutput(0), iMath(0), hwnd(0) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Vector positioning in metres
|
||||
*/
|
||||
struct QSVECTOR {
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
|
||||
QSVECTOR() : x(0.0), y(0.0), z(0.0) {}
|
||||
QSVECTOR(double xp, double yp, double zp) : x(xp), y(yp), z(zp) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Polar positioning
|
||||
*/
|
||||
struct QSPOLAR {
|
||||
double azimuth; // degrees
|
||||
double range; // meters
|
||||
double elevation; // degrees
|
||||
|
||||
QSPOLAR() : azimuth(0.0), range(0.0), elevation(0.0) {}
|
||||
QSPOLAR(double azimuth_, double range_, double elevation_) :
|
||||
azimuth(azimuth_), range(range_), elevation(elevation_) {}
|
||||
};
|
||||
|
||||
struct QMIX_DISTANCES {
|
||||
int cbSize; // Structure size
|
||||
double minDistance; // sounds are at full volume if closer than this
|
||||
double maxDistance; // sounds are muted if further away than this
|
||||
double scale; // relative amount to adjust rolloff by
|
||||
|
||||
QMIX_DISTANCES() : cbSize(16), minDistance(0.0), maxDistance(0.0), scale(0.0) {}
|
||||
QMIX_DISTANCES(double minDistance_, double maxDistance_, double scale_) :
|
||||
cbSize(16), minDistance(minDistance_), maxDistance(maxDistance_), scale(scale_) {}
|
||||
};
|
||||
|
||||
typedef void (*LPQMIXDONECALLBACK)(int iChannel, CWaveFile *lpWave, void *dwUser);
|
||||
|
||||
struct QMIXPLAYPARAMS {
|
||||
uint dwSize; // Size of the play structure
|
||||
void *lpImage; // Additional preprocessed audio for high performance
|
||||
uint hwndNotify; // if set, WOM_OPEN and WOM_DONE messages sent to that window
|
||||
LPQMIXDONECALLBACK callback; // Callback function
|
||||
void *dwUser; // User data accompanying callback
|
||||
int lStart;
|
||||
int lStartLoop;
|
||||
int lEndLoop;
|
||||
int lEnd;
|
||||
const void *lpChannelParams; // initialize with these parameters
|
||||
// Properties introduced by ScummVM
|
||||
Audio::Mixer::SoundType _soundType;
|
||||
|
||||
QMIXPLAYPARAMS() : dwSize(36), lpImage(nullptr), hwndNotify(0), callback(nullptr),
|
||||
dwUser(nullptr), lStart(0), lStartLoop(0), lEndLoop(0), lEnd(0),
|
||||
lpChannelParams(nullptr), _soundType(Audio::Mixer::kPlainSoundType) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents an interface to the QMixer library developed by
|
||||
* QSound Labs, Inc. Which itself is apparently based on Microsoft's
|
||||
* WaveMix API.
|
||||
*
|
||||
* It does not currently have any actual code from the library,
|
||||
* and instead remaps calls to ScummVM's existing mixer where possible.
|
||||
* This means that advanced features of the QMixer library, like being
|
||||
* able to set up both the player and sounds at different positions are
|
||||
* currently ignored, and all sounds play at full volume.
|
||||
*/
|
||||
class QMixer {
|
||||
struct SoundEntry {
|
||||
bool _started;
|
||||
CWaveFile *_waveFile;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
LPQMIXDONECALLBACK _callback;
|
||||
int _loops;
|
||||
void *_userData;
|
||||
SoundEntry() : _started(false), _waveFile(nullptr), _callback(nullptr),
|
||||
_loops(0), _userData(nullptr) {}
|
||||
|
||||
SoundEntry(CWaveFile *waveFile, LPQMIXDONECALLBACK callback, int loops, void *userData) :
|
||||
_started(false), _waveFile(waveFile), _callback(callback), _loops(loops), _userData(userData) {}
|
||||
};
|
||||
struct ChannelEntry {
|
||||
// Currently playing and any following queued sounds for the channel
|
||||
Common::List<SoundEntry> _sounds;
|
||||
// Current channel volume
|
||||
byte _volume;
|
||||
// Current time in milliseconds for paning (volume) changes
|
||||
uint _panRate;
|
||||
// Fields used to transition between volume levels
|
||||
uint _volumeChangeStart;
|
||||
uint _volumeChangeEnd;
|
||||
byte _volumeStart;
|
||||
byte _volumeEnd;
|
||||
// Distance of source
|
||||
double _distance;
|
||||
bool _resetDistance;
|
||||
|
||||
ChannelEntry() : _volume(0), _panRate(0), _volumeChangeStart(0),
|
||||
_volumeChangeEnd(0), _volumeStart(0), _volumeEnd(0),
|
||||
_distance(0.0), _resetDistance(true) {}
|
||||
|
||||
/**
|
||||
* Calculates the raw volume level to pass to ScummVM playStream, taking
|
||||
* into the sound's volume level and distance from origin
|
||||
*/
|
||||
byte getRawVolume() const;
|
||||
};
|
||||
private:
|
||||
Common::Array<ChannelEntry> _channels;
|
||||
protected:
|
||||
Audio::Mixer *_mixer;
|
||||
public:
|
||||
QMixer(Audio::Mixer *mixer);
|
||||
virtual ~QMixer();
|
||||
|
||||
/**
|
||||
* Initializes the mixer
|
||||
*/
|
||||
bool qsWaveMixInitEx(const QMIXCONFIG &config);
|
||||
|
||||
/**
|
||||
* Activates the mixer
|
||||
*/
|
||||
void qsWaveMixActivate(bool fActivate);
|
||||
|
||||
/**
|
||||
* Opens channels in the mixer for access
|
||||
*/
|
||||
int qsWaveMixOpenChannel(int iChannel, QMixFlag mode);
|
||||
|
||||
/**
|
||||
* Enables a given channel
|
||||
*/
|
||||
int qsWaveMixEnableChannel(int iChannel, uint flags, bool enabled);
|
||||
|
||||
/**
|
||||
* Closes down the mixer
|
||||
*/
|
||||
void qsWaveMixCloseSession();
|
||||
|
||||
/**
|
||||
* Stops a sound from playing
|
||||
*/
|
||||
void qsWaveMixFreeWave(Audio::SoundHandle &handle);
|
||||
|
||||
/**
|
||||
* Flushes a channel
|
||||
*/
|
||||
void qsWaveMixFlushChannel(int iChannel, uint flags = 0);
|
||||
|
||||
/**
|
||||
* Sets the amount of time, in milliseconds, to effect a change in
|
||||
* a channel property (e.g. volume, position). Non-zero values
|
||||
* smooth out changes
|
||||
* @param iChannel Channel to change
|
||||
* @param flags Flags
|
||||
* @param rate Pan rate in milliseconds
|
||||
*/
|
||||
void qsWaveMixSetPanRate(int iChannel, uint flags, uint rate);
|
||||
|
||||
/**
|
||||
* Sets the volume for a channel
|
||||
*/
|
||||
void qsWaveMixSetVolume(int iChannel, uint flags, uint volume);
|
||||
|
||||
/**
|
||||
* Sets the relative position of a channel
|
||||
* @param iChannel Channel number
|
||||
* @param Flags Flags
|
||||
* @param position Vector position for channel
|
||||
*/
|
||||
void qsWaveMixSetSourcePosition(int iChannel, uint flags, const QSVECTOR &position);
|
||||
|
||||
/**
|
||||
* Sets the relative position of a channel using polar co-ordinates
|
||||
* @param iChannel Channel number
|
||||
* @param Flags Flags
|
||||
* @param position Polar position for channel
|
||||
*/
|
||||
void qsWaveMixSetPolarPosition(int iChannel, uint flags, const QSPOLAR &position);
|
||||
|
||||
/**
|
||||
* Sets the listener position
|
||||
*/
|
||||
void qsWaveMixSetListenerPosition(const QSVECTOR &position, uint flags = 0);
|
||||
|
||||
/**
|
||||
* Sets the listener orientation
|
||||
*/
|
||||
void qsWaveMixSetListenerOrientation(const QSVECTOR &direction, const QSVECTOR &up, uint flags = 0);
|
||||
|
||||
/**
|
||||
* Sets the mapping ditance range
|
||||
*/
|
||||
void qsWaveMixSetDistanceMapping(int iChannel, uint flags, const QMIX_DISTANCES &distances);
|
||||
|
||||
/**
|
||||
* Sets the frequency/rate of sound playback
|
||||
*/
|
||||
void qsWaveMixSetFrequency(int iChannel, uint flags, uint frequency);
|
||||
|
||||
/**
|
||||
* Sets the velocity of the source (listener)
|
||||
*/
|
||||
void qsWaveMixSetSourceVelocity(int iChannel, uint flags, const QSVECTOR &velocity);
|
||||
|
||||
/**
|
||||
* Plays sound
|
||||
* @param iChannel The channel number to be played on
|
||||
* @param flags Play flags
|
||||
* @param mixWave Data for the sound to be played
|
||||
* @param loops Number of loops to play (-1 for forever)
|
||||
* @param params Playback parameter data
|
||||
*/
|
||||
int qsWaveMixPlayEx(int iChannel, uint flags, CWaveFile *waveFile, int loops, const QMIXPLAYPARAMS ¶ms);
|
||||
|
||||
/**
|
||||
* Returns true if there are no more buffers playing or queued on the channel
|
||||
*/
|
||||
bool qsWaveMixIsChannelDone(int iChannel) const;
|
||||
|
||||
/**
|
||||
* Handles regularly updating the mixer
|
||||
*/
|
||||
void qsWaveMixPump();
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_QMIXER_H */
|
||||
78
engines/titanic/sound/restricted_auto_music_player.cpp
Normal file
78
engines/titanic/sound/restricted_auto_music_player.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/restricted_auto_music_player.h"
|
||||
#include "titanic/core/room_item.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CRestrictedAutoMusicPlayer, CAutoMusicPlayer)
|
||||
ON_MESSAGE(EnterRoomMsg)
|
||||
ON_MESSAGE(LeaveRoomMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CRestrictedAutoMusicPlayer::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeQuotedLine(_oldNodeName, indent);
|
||||
file->writeQuotedLine(_newNodeName, indent);
|
||||
file->writeQuotedLine(_newRoomName, indent);
|
||||
file->writeQuotedLine(_oldRoomName, indent);
|
||||
|
||||
CAutoMusicPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CRestrictedAutoMusicPlayer::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_oldNodeName = file->readString();
|
||||
_newNodeName = file->readString();
|
||||
_newRoomName = file->readString();
|
||||
_oldRoomName = file->readString();
|
||||
|
||||
CAutoMusicPlayer::load(file);
|
||||
}
|
||||
|
||||
bool CRestrictedAutoMusicPlayer::EnterRoomMsg(CEnterRoomMsg *msg) {
|
||||
if (!msg->_oldRoom)
|
||||
return true;
|
||||
if (petCheckNode(_oldNodeName))
|
||||
return false;
|
||||
|
||||
CString roomName = msg->_oldRoom->getName();
|
||||
if (!_oldRoomName.compareToIgnoreCase(roomName)) {
|
||||
_isEnabled = true;
|
||||
return false;
|
||||
} else {
|
||||
return CAutoMusicPlayer::EnterRoomMsg(msg);
|
||||
}
|
||||
}
|
||||
|
||||
bool CRestrictedAutoMusicPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) {
|
||||
CString roomName = msg->_newRoom->getName();
|
||||
|
||||
if (petCheckNode(_newNodeName) || !_newRoomName.compareToIgnoreCase(roomName)) {
|
||||
_isEnabled = false;
|
||||
return true;
|
||||
} else {
|
||||
return CAutoMusicPlayer::LeaveRoomMsg(msg);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
55
engines/titanic/sound/restricted_auto_music_player.h
Normal file
55
engines/titanic/sound/restricted_auto_music_player.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_RESTRICTED_AUTO_MUSIC_PLAYER_H
|
||||
#define TITANIC_RESTRICTED_AUTO_MUSIC_PLAYER_H
|
||||
|
||||
#include "titanic/sound/auto_music_player.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CRestrictedAutoMusicPlayer : public CAutoMusicPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool EnterRoomMsg(CEnterRoomMsg *msg);
|
||||
bool LeaveRoomMsg(CLeaveRoomMsg *msg);
|
||||
private:
|
||||
CString _oldNodeName;
|
||||
CString _newNodeName;
|
||||
CString _newRoomName;
|
||||
CString _oldRoomName;
|
||||
public:
|
||||
CLASSDEF;
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_RESTRICTED_AUTO_MUSIC_PLAYER_H */
|
||||
61
engines/titanic/sound/room_auto_sound_player.cpp
Normal file
61
engines/titanic/sound/room_auto_sound_player.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/room_auto_sound_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CRoomAutoSoundPlayer, CAutoSoundPlayer)
|
||||
ON_MESSAGE(EnterRoomMsg)
|
||||
ON_MESSAGE(LeaveRoomMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CRoomAutoSoundPlayer::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
CAutoSoundPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CRoomAutoSoundPlayer::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
CAutoSoundPlayer::load(file);
|
||||
}
|
||||
|
||||
bool CRoomAutoSoundPlayer::EnterRoomMsg(CEnterRoomMsg *msg) {
|
||||
CRoomItem *room = findRoom();
|
||||
if (room == msg->_newRoom) {
|
||||
CTurnOn onMsg;
|
||||
onMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRoomAutoSoundPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) {
|
||||
CRoomItem *room = findRoom();
|
||||
if (room == msg->_oldRoom) {
|
||||
CTurnOff offMsg;
|
||||
offMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
50
engines/titanic/sound/room_auto_sound_player.h
Normal file
50
engines/titanic/sound/room_auto_sound_player.h
Normal file
@@ -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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_ROOM_AUTO_SOUND_PLAYER_H
|
||||
#define TITANIC_ROOM_AUTO_SOUND_PLAYER_H
|
||||
|
||||
#include "titanic/sound/auto_sound_player.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CRoomAutoSoundPlayer : public CAutoSoundPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool EnterRoomMsg(CEnterRoomMsg *msg);
|
||||
bool LeaveRoomMsg(CLeaveRoomMsg *msg);
|
||||
public:
|
||||
CLASSDEF;
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_ROOM_AUTO_SOUND_PLAYER_H */
|
||||
61
engines/titanic/sound/room_trigger_auto_music_player.cpp
Normal file
61
engines/titanic/sound/room_trigger_auto_music_player.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/room_trigger_auto_music_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CRoomTriggerAutoMusicPlayer, CTriggerAutoMusicPlayer)
|
||||
ON_MESSAGE(LeaveRoomMsg)
|
||||
ON_MESSAGE(EnterRoomMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CRoomTriggerAutoMusicPlayer::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
CTriggerAutoMusicPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CRoomTriggerAutoMusicPlayer::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
CTriggerAutoMusicPlayer::load(file);
|
||||
}
|
||||
|
||||
bool CRoomTriggerAutoMusicPlayer::LeaveRoomMsg(CLeaveRoomMsg *msg) {
|
||||
if (msg->_oldRoom == findRoom()) {
|
||||
CTriggerAutoMusicPlayerMsg triggerMsg;
|
||||
triggerMsg._value = 1;
|
||||
triggerMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRoomTriggerAutoMusicPlayer::EnterRoomMsg(CEnterRoomMsg *msg) {
|
||||
if (msg->_newRoom == findRoom()) {
|
||||
CTriggerAutoMusicPlayerMsg triggerMsg;
|
||||
triggerMsg._value = 2;
|
||||
triggerMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
50
engines/titanic/sound/room_trigger_auto_music_player.h
Normal file
50
engines/titanic/sound/room_trigger_auto_music_player.h
Normal file
@@ -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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_ROOM_TRIGGER_AUTO_MUSIC_PLAYER_H
|
||||
#define TITANIC_ROOM_TRIGGER_AUTO_MUSIC_PLAYER_H
|
||||
|
||||
#include "titanic/sound/trigger_auto_music_player.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CRoomTriggerAutoMusicPlayer : public CTriggerAutoMusicPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool LeaveRoomMsg(CLeaveRoomMsg *msg);
|
||||
bool EnterRoomMsg(CEnterRoomMsg *msg);
|
||||
public:
|
||||
CLASSDEF;
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_ROOM_TRIGGER_AUTO_MUSIC_PLAYER_H */
|
||||
115
engines/titanic/sound/season_noises.cpp
Normal file
115
engines/titanic/sound/season_noises.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/season_noises.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSeasonNoises, CViewAutoSoundPlayer)
|
||||
ON_MESSAGE(ChangeSeasonMsg)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(ActMsg)
|
||||
ON_MESSAGE(LoadSuccessMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CSeasonNoises::CSeasonNoises() : CViewAutoSoundPlayer(), _seasonNumber(SEASON_SUMMER),
|
||||
_springName("NULL"), _summerName("NULL"), _autumnName("NULL"), _winterName("NULL") {
|
||||
}
|
||||
|
||||
void CSeasonNoises::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_seasonNumber, indent);
|
||||
file->writeQuotedLine(_springName, indent);
|
||||
file->writeQuotedLine(_summerName, indent);
|
||||
file->writeQuotedLine(_autumnName, indent);
|
||||
file->writeQuotedLine(_winterName, indent);
|
||||
|
||||
CViewAutoSoundPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CSeasonNoises::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_seasonNumber = (Season)file->readNumber();
|
||||
_springName = file->readString();
|
||||
_summerName = file->readString();
|
||||
_autumnName = file->readString();
|
||||
_winterName = file->readString();
|
||||
|
||||
CViewAutoSoundPlayer::load(file);
|
||||
}
|
||||
|
||||
bool CSeasonNoises::ChangeSeasonMsg(CChangeSeasonMsg *msg) {
|
||||
_seasonNumber = (Season)(((int)_seasonNumber + 1) % 4);
|
||||
CActMsg actMsg("Update");
|
||||
actMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSeasonNoises::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
CActMsg actMsg("Update");
|
||||
actMsg.execute(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSeasonNoises::ActMsg(CActMsg *msg) {
|
||||
msg->_action = "Update";
|
||||
|
||||
switch (_seasonNumber) {
|
||||
case SEASON_SUMMER:
|
||||
_filename = _summerName;
|
||||
break;
|
||||
case SEASON_AUTUMN:
|
||||
_filename = _autumnName;
|
||||
break;
|
||||
case SEASON_WINTER:
|
||||
_filename = _winterName;
|
||||
break;
|
||||
case SEASON_SPRING:
|
||||
_filename = _springName;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CSignalObject signalMsg;
|
||||
signalMsg._numValue = 2;
|
||||
signalMsg.execute(this);
|
||||
|
||||
CTurnOn onMsg;
|
||||
onMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSeasonNoises::LoadSuccessMsg(CLoadSuccessMsg *msg) {
|
||||
if (_active) {
|
||||
_active = false;
|
||||
_soundHandle = -1;
|
||||
|
||||
CActMsg actMsg("Update");
|
||||
actMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
58
engines/titanic/sound/season_noises.h
Normal file
58
engines/titanic/sound/season_noises.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_SEASON_NOISES_H
|
||||
#define TITANIC_SEASON_NOISES_H
|
||||
|
||||
#include "titanic/sound/view_auto_sound_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CSeasonNoises : public CViewAutoSoundPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool ChangeSeasonMsg(CChangeSeasonMsg *msg);
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool ActMsg(CActMsg *msg);
|
||||
bool LoadSuccessMsg(CLoadSuccessMsg *msg);
|
||||
private:
|
||||
Season _seasonNumber;
|
||||
CString _springName;
|
||||
CString _summerName;
|
||||
CString _autumnName;
|
||||
CString _winterName;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CSeasonNoises();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_SEASON_NOISES_H */
|
||||
135
engines/titanic/sound/seasonal_music_player.cpp
Normal file
135
engines/titanic/sound/seasonal_music_player.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/seasonal_music_player.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSeasonalMusicPlayer, CAutoMusicPlayerBase)
|
||||
ON_MESSAGE(ChangeSeasonMsg)
|
||||
ON_MESSAGE(ArboretumGateMsg)
|
||||
ON_MESSAGE(ChangeMusicMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CSeasonalMusicPlayer::CSeasonalMusicPlayer() : CAutoMusicPlayerBase() {
|
||||
_isSpring = false;
|
||||
_isSummer = true;
|
||||
_isAutumn = false;
|
||||
_isWinter = false;
|
||||
_springMode = VOL_MUTE;
|
||||
_summerMode = VOL_QUIET;
|
||||
_autumnMode = VOL_MUTE;
|
||||
_winterMode = VOL_MUTE;
|
||||
}
|
||||
|
||||
void CSeasonalMusicPlayer::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_isSpring, indent);
|
||||
file->writeNumberLine(_isSummer, indent);
|
||||
file->writeNumberLine(_isAutumn, indent);
|
||||
file->writeNumberLine(_isWinter, indent);
|
||||
file->writeNumberLine(_springMode, indent);
|
||||
file->writeNumberLine(_summerMode, indent);
|
||||
file->writeNumberLine(_autumnMode, indent);
|
||||
file->writeNumberLine(_winterMode, indent);
|
||||
|
||||
CAutoMusicPlayerBase::save(file, indent);
|
||||
}
|
||||
|
||||
void CSeasonalMusicPlayer::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_isSpring = file->readNumber();
|
||||
_isSummer = file->readNumber();
|
||||
_isAutumn = file->readNumber();
|
||||
_isWinter = file->readNumber();
|
||||
_springMode = (VolumeMode)file->readNumber();
|
||||
_summerMode = (VolumeMode)file->readNumber();
|
||||
_autumnMode = (VolumeMode)file->readNumber();
|
||||
_winterMode = (VolumeMode)file->readNumber();
|
||||
|
||||
CAutoMusicPlayerBase::load(file);
|
||||
}
|
||||
|
||||
bool CSeasonalMusicPlayer::ChangeSeasonMsg(CChangeSeasonMsg *msg) {
|
||||
_isSpring = msg->_season == "spring";
|
||||
_isSummer = msg->_season == "summer";
|
||||
_isAutumn = msg->_season == "autumn";
|
||||
_isWinter = msg->_season == "winter";
|
||||
|
||||
_springMode = _isSpring ? VOL_QUIET : VOL_MUTE;
|
||||
_summerMode = _isSummer ? VOL_QUIET : VOL_MUTE;
|
||||
_autumnMode = _isAutumn ? VOL_QUIET : VOL_MUTE;
|
||||
_winterMode = _isWinter ? VOL_QUIET : VOL_MUTE;
|
||||
|
||||
CChangeMusicMsg changeMsg;
|
||||
changeMsg._filename = msg->_season;
|
||||
changeMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSeasonalMusicPlayer::ArboretumGateMsg(CArboretumGateMsg *msg) {
|
||||
CChangeMusicMsg changeMsg;
|
||||
changeMsg._action = msg->_value ? MUSIC_START : MUSIC_STOP;
|
||||
changeMsg.execute(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSeasonalMusicPlayer::ChangeMusicMsg(CChangeMusicMsg *msg) {
|
||||
if (_isEnabled && msg->_action == MUSIC_STOP) {
|
||||
_isEnabled = false;
|
||||
stopAmbientSound(_transition, -1);
|
||||
}
|
||||
|
||||
if (!msg->_filename.empty()) {
|
||||
if (_isSummer) {
|
||||
setAmbientSoundVolume(VOL_MUTE, 2, 0);
|
||||
setAmbientSoundVolume(VOL_QUIET, 2, 1);
|
||||
} else if (_isAutumn) {
|
||||
setAmbientSoundVolume(VOL_MUTE, 2, 1);
|
||||
setAmbientSoundVolume(VOL_QUIET, 2, 2);
|
||||
} else if (_isWinter) {
|
||||
setAmbientSoundVolume(VOL_MUTE, 2, 2);
|
||||
setAmbientSoundVolume(VOL_QUIET, 2, 3);
|
||||
} else if (_isSpring) {
|
||||
setAmbientSoundVolume(VOL_MUTE, 2, 3);
|
||||
setAmbientSoundVolume(VOL_QUIET, 2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_isEnabled && msg->_action == MUSIC_START) {
|
||||
_isEnabled = true;
|
||||
loadSound(TRANSLATE("c#64.wav", "c#47.wav"));
|
||||
loadSound(TRANSLATE("c#63.wav", "c#46.wav"));
|
||||
loadSound(TRANSLATE("c#65.wav", "c#48.wav"));
|
||||
loadSound(TRANSLATE("c#62.wav", "c#47.wav"));
|
||||
playAmbientSound(TRANSLATE("c#64.wav", "c#47.wav"), _springMode, _isSpring, true, 0);
|
||||
playAmbientSound(TRANSLATE("c#63.wav", "c#46.wav"), _summerMode, _isSummer, true, 1);
|
||||
playAmbientSound(TRANSLATE("c#65.wav", "c#48.wav"), _autumnMode, _isAutumn, true, 2);
|
||||
playAmbientSound(TRANSLATE("c#62.wav", "c#47.wav"), _winterMode, _isWinter, true, 3);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
60
engines/titanic/sound/seasonal_music_player.h
Normal file
60
engines/titanic/sound/seasonal_music_player.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_SEASONAL_MUSIC_PLAYER_H
|
||||
#define TITANIC_SEASONAL_MUSIC_PLAYER_H
|
||||
|
||||
#include "titanic/sound/auto_music_player_base.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CSeasonalMusicPlayer : public CAutoMusicPlayerBase {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool ChangeSeasonMsg(CChangeSeasonMsg *msg);
|
||||
bool ArboretumGateMsg(CArboretumGateMsg *msg);
|
||||
bool ChangeMusicMsg(CChangeMusicMsg *msg);
|
||||
private:
|
||||
bool _isSpring;
|
||||
bool _isSummer;
|
||||
bool _isAutumn;
|
||||
bool _isWinter;
|
||||
VolumeMode _springMode;
|
||||
VolumeMode _summerMode;
|
||||
VolumeMode _autumnMode;
|
||||
VolumeMode _winterMode;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CSeasonalMusicPlayer();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_SEASONAL_MUSIC_PLAYER_H */
|
||||
243
engines/titanic/sound/sound.cpp
Normal file
243
engines/titanic/sound/sound.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/sound.h"
|
||||
#include "titanic/game_manager.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
CSoundItem::~CSoundItem() {
|
||||
delete _waveFile;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
CSound::CSound(CGameManager *owner, Audio::Mixer *mixer) :
|
||||
_gameManager(owner), _soundManager(mixer) {
|
||||
g_vm->_movieManager.setSoundManager(&_soundManager);
|
||||
}
|
||||
|
||||
CSound::~CSound() {
|
||||
_soundManager.qsWaveMixCloseSession();
|
||||
_sounds.destroyContents();
|
||||
}
|
||||
|
||||
void CSound::save(SimpleFile *file) const {
|
||||
_soundManager.save(file);
|
||||
}
|
||||
|
||||
void CSound::load(SimpleFile *file) {
|
||||
_soundManager.load(file);
|
||||
}
|
||||
|
||||
void CSound::preLoad() {
|
||||
_soundManager.preLoad();
|
||||
|
||||
if (_gameManager)
|
||||
_gameManager->_musicRoom.destroyMusicHandler();
|
||||
}
|
||||
|
||||
void CSound::preEnterView(CViewItem *newView, bool isNewRoom) {
|
||||
CNodeItem *node = newView->findNode();
|
||||
double xp, yp, zp;
|
||||
node->getPosition(xp, yp, zp);
|
||||
|
||||
double cosVal = cos(newView->_angle);
|
||||
double sinVal = -sin(newView->_angle);
|
||||
|
||||
_soundManager.setListenerPosition(xp, yp, zp, cosVal, sinVal, 0, isNewRoom);
|
||||
}
|
||||
|
||||
bool CSound::isActive(int handle) {
|
||||
if (handle != 0 && handle != -1)
|
||||
return _soundManager.isActive(handle);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CSound::setVolume(uint handle, uint volume, uint seconds) {
|
||||
_soundManager.setVolume(handle, volume, seconds);
|
||||
}
|
||||
|
||||
void CSound::activateSound(CWaveFile *waveFile, DisposeAfterUse::Flag disposeAfterUse) {
|
||||
for (CSoundItemList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
|
||||
CSoundItem *sound = *i;
|
||||
if (sound->_waveFile == waveFile) {
|
||||
sound->_active = true;
|
||||
sound->_disposeAfterUse = disposeAfterUse;
|
||||
|
||||
// Anything bigger than 50Kb is automatically flagged to be free when finished
|
||||
if (waveFile->size() > (50 * 1024))
|
||||
sound->_disposeAfterUse = DisposeAfterUse::YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSound::stopChannel(int channel) {
|
||||
_soundManager.stopChannel(channel);
|
||||
}
|
||||
|
||||
void CSound::checkSounds() {
|
||||
for (CSoundItemList::iterator i = _sounds.begin(); i != _sounds.end(); ) {
|
||||
CSoundItem *soundItem = *i;
|
||||
|
||||
if (soundItem->_active && soundItem->_disposeAfterUse == DisposeAfterUse::YES) {
|
||||
if (!_soundManager.isActive(soundItem->_waveFile)) {
|
||||
i = _sounds.erase(i);
|
||||
delete soundItem;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void CSound::removeOldest() {
|
||||
for (CSoundItemList::iterator i = _sounds.reverse_begin();
|
||||
i != _sounds.end(); --i) {
|
||||
CSoundItem *soundItem = *i;
|
||||
if (soundItem->_active && !_soundManager.isActive(soundItem->_waveFile)) {
|
||||
_sounds.remove(soundItem);
|
||||
delete soundItem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CWaveFile *CSound::getTrueTalkSound(CDialogueFile *dialogueFile, int index) {
|
||||
return loadSpeech(dialogueFile, index);
|
||||
}
|
||||
|
||||
CWaveFile *CSound::loadSound(const CString &name) {
|
||||
checkSounds();
|
||||
|
||||
// Check whether an entry for the given name is already active
|
||||
for (CSoundItemList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
|
||||
CSoundItem *soundItem = *i;
|
||||
if (soundItem->_name == name) {
|
||||
// Found it, so move it to the front of the list and return
|
||||
_sounds.remove(soundItem);
|
||||
_sounds.push_front(soundItem);
|
||||
return soundItem->_waveFile;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new sound item
|
||||
CSoundItem *soundItem = new CSoundItem(name);
|
||||
soundItem->_waveFile = _soundManager.loadSound(name);
|
||||
|
||||
if (!soundItem->_waveFile) {
|
||||
// Couldn't load sound, so destroy new item and return
|
||||
delete soundItem;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add the item to the list of sounds
|
||||
_sounds.push_front(soundItem);
|
||||
|
||||
// If there are more than 10 sounds loaded, remove the last one,
|
||||
// which is the least recently used of all of them
|
||||
if (_sounds.size() > 10)
|
||||
removeOldest();
|
||||
|
||||
return soundItem->_waveFile;
|
||||
}
|
||||
|
||||
int CSound::playSound(const CString &name, CProximity &prox) {
|
||||
CWaveFile *waveFile = loadSound(name);
|
||||
if (!waveFile)
|
||||
return -1;
|
||||
|
||||
prox._soundDuration = waveFile->getDurationTicks();
|
||||
if (prox._soundType != Audio::Mixer::kPlainSoundType)
|
||||
waveFile->_soundType = prox._soundType;
|
||||
|
||||
activateSound(waveFile, prox._disposeAfterUse);
|
||||
|
||||
return _soundManager.playSound(*waveFile, prox);
|
||||
}
|
||||
|
||||
CWaveFile *CSound::loadSpeech(CDialogueFile *dialogueFile, int speechId) {
|
||||
checkSounds();
|
||||
|
||||
// Check whether an entry for the given name is already active
|
||||
for (CSoundItemList::iterator i = _sounds.begin(); i != _sounds.end(); ++i) {
|
||||
CSoundItem *soundItem = *i;
|
||||
if (soundItem->_dialogueFileHandle == dialogueFile->getFile()
|
||||
&& soundItem->_speechId == speechId) {
|
||||
// Found it, so move it to the front of the list and return
|
||||
_sounds.remove(soundItem);
|
||||
_sounds.push_front(soundItem);
|
||||
return soundItem->_waveFile;
|
||||
}
|
||||
}
|
||||
|
||||
// Create new sound item
|
||||
CSoundItem *soundItem = new CSoundItem(dialogueFile->getFile(), speechId);
|
||||
soundItem->_waveFile = _soundManager.loadSpeech(dialogueFile, speechId);
|
||||
|
||||
if (!soundItem->_waveFile) {
|
||||
// Couldn't load speech, so destroy new item and return
|
||||
delete soundItem;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add the item to the list of sounds
|
||||
_sounds.push_front(soundItem);
|
||||
|
||||
// If there are more than 10 sounds loaded, remove the last one,
|
||||
// which is the least recently used of all of them
|
||||
if (_sounds.size() > 10)
|
||||
removeOldest();
|
||||
|
||||
return soundItem->_waveFile;
|
||||
}
|
||||
|
||||
int CSound::playSpeech(CDialogueFile *dialogueFile, int speechId, CProximity &prox) {
|
||||
CWaveFile *waveFile = loadSpeech(dialogueFile, speechId);
|
||||
if (!waveFile)
|
||||
return -1;
|
||||
|
||||
prox._soundDuration = waveFile->getDurationTicks();
|
||||
if (prox._soundType != Audio::Mixer::kPlainSoundType)
|
||||
waveFile->_soundType = prox._soundType;
|
||||
|
||||
activateSound(waveFile, prox._disposeAfterUse);
|
||||
return _soundManager.playSound(*waveFile, prox);
|
||||
}
|
||||
|
||||
void CSound::stopSound(uint handle) {
|
||||
_soundManager.stopSound(handle);
|
||||
}
|
||||
|
||||
void CSound::setCanFree(int handle) {
|
||||
if (handle != 0 && handle != -1)
|
||||
_soundManager.setCanFree(handle);
|
||||
}
|
||||
|
||||
void CSound::updateMixer() {
|
||||
_soundManager.waveMixPump();
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
194
engines/titanic/sound/sound.h
Normal file
194
engines/titanic/sound/sound.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_SOUND_H
|
||||
#define TITANIC_SOUND_H
|
||||
|
||||
#include "titanic/support/simple_file.h"
|
||||
#include "titanic/sound/proximity.h"
|
||||
#include "titanic/sound/sound_manager.h"
|
||||
#include "titanic/sound/wave_file.h"
|
||||
#include "titanic/core/list.h"
|
||||
#include "titanic/core/view_item.h"
|
||||
#include "titanic/true_talk/dialogue_file.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CGameManager;
|
||||
|
||||
class CSoundItem : public ListItem {
|
||||
public:
|
||||
CString _name;
|
||||
CWaveFile *_waveFile;
|
||||
File *_dialogueFileHandle;
|
||||
int _speechId;
|
||||
DisposeAfterUse::Flag _disposeAfterUse;
|
||||
bool _active;
|
||||
public:
|
||||
CSoundItem() : ListItem(), _waveFile(nullptr), _dialogueFileHandle(nullptr),
|
||||
_speechId(0), _disposeAfterUse(DisposeAfterUse::NO), _active(false) {}
|
||||
CSoundItem(const CString &name) : ListItem(), _name(name), _waveFile(nullptr),
|
||||
_dialogueFileHandle(nullptr), _disposeAfterUse(DisposeAfterUse::NO),
|
||||
_speechId(0), _active(false) {}
|
||||
CSoundItem(File *dialogueFile, int speechId) : ListItem(), _waveFile(nullptr),
|
||||
_dialogueFileHandle(dialogueFile), _speechId(speechId), _active(false),
|
||||
_disposeAfterUse(DisposeAfterUse::NO) {}
|
||||
~CSoundItem() override;
|
||||
};
|
||||
|
||||
class CSoundItemList : public List<CSoundItem> {
|
||||
};
|
||||
|
||||
class CSound {
|
||||
private:
|
||||
CGameManager *_gameManager;
|
||||
CSoundItemList _sounds;
|
||||
private:
|
||||
/**
|
||||
* Check whether any sounds are done and can be be removed
|
||||
*/
|
||||
void checkSounds();
|
||||
|
||||
/**
|
||||
* Removes the oldest sound from the sounds list that isn't
|
||||
* currently playing
|
||||
*/
|
||||
void removeOldest();
|
||||
public:
|
||||
QSoundManager _soundManager;
|
||||
public:
|
||||
CSound(CGameManager *owner, Audio::Mixer *mixer);
|
||||
~CSound();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file) const;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file);
|
||||
|
||||
/**
|
||||
* Called when a game is about to be loaded
|
||||
*/
|
||||
void preLoad();
|
||||
|
||||
/**
|
||||
* Called when loading a game is complete
|
||||
*/
|
||||
void postLoad() { _soundManager.postLoad(); }
|
||||
|
||||
/**
|
||||
* Called when a game is about to be saved
|
||||
*/
|
||||
void preSave() { _soundManager.preSave(); }
|
||||
|
||||
/**
|
||||
* Called when a game has finished being saved
|
||||
*/
|
||||
void postSave() { _soundManager.postSave(); }
|
||||
|
||||
/**
|
||||
* Called when the view has been changed
|
||||
*/
|
||||
void preEnterView(CViewItem *newView, bool isNewRoom);
|
||||
|
||||
/**
|
||||
* Returns true if a sound with the specified handle is active
|
||||
*/
|
||||
bool isActive(int handle);
|
||||
|
||||
/**
|
||||
* Sets the volume for a sound
|
||||
* @param handle Sound handle
|
||||
* @param volume Volume percentage (0 to 100)
|
||||
* @param seconds Number of seconds to transition to the new volume
|
||||
*/
|
||||
void setVolume(uint handle, uint volume, uint seconds);
|
||||
|
||||
/**
|
||||
* Flags a sound about to be played as activated
|
||||
*/
|
||||
void activateSound(CWaveFile *waveFile,
|
||||
DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::NO);
|
||||
|
||||
/**
|
||||
* Stops any sounds attached to a given channel
|
||||
*/
|
||||
void stopChannel(int channel);
|
||||
|
||||
/**
|
||||
* Loads a TrueTalk dialogue
|
||||
* @param dialogueFile Dialogue file reference
|
||||
* @param speechId Speech Id within dialogue
|
||||
* @returns Wave file instance
|
||||
*/
|
||||
CWaveFile *getTrueTalkSound(CDialogueFile *dialogueFile, int index);
|
||||
|
||||
/**
|
||||
* Load a speech resource
|
||||
* @param dialogueFile Dialogue file reference
|
||||
* @param speechId Speech Id within dialogue
|
||||
* @returns Wave file instance
|
||||
*/
|
||||
CWaveFile *loadSpeech(CDialogueFile *dialogueFile, int speechId);
|
||||
|
||||
/**
|
||||
* Play a speech
|
||||
* @param dialogueFile Dialogue file reference
|
||||
* @param speechId Speech Id within dialogue
|
||||
* @param prox Proximity instance
|
||||
*/
|
||||
int playSpeech(CDialogueFile *dialogueFile, int speechId, CProximity &prox);
|
||||
|
||||
/**
|
||||
* Load a sound
|
||||
* @param name Name of sound resource
|
||||
* @returns Sound item record
|
||||
*/
|
||||
CWaveFile *loadSound(const CString &name);
|
||||
|
||||
/**
|
||||
* Play a sound
|
||||
*/
|
||||
int playSound(const CString &name, CProximity &prox);
|
||||
|
||||
/**
|
||||
* Stop a sound
|
||||
*/
|
||||
void stopSound(uint handle);
|
||||
|
||||
/**
|
||||
* Flags that a sound can be freed if a timeout is set
|
||||
*/
|
||||
void setCanFree(int handle);
|
||||
|
||||
/**
|
||||
* Handles regularly updating the mixer
|
||||
*/
|
||||
void updateMixer();
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_SOUND_H */
|
||||
498
engines/titanic/sound/sound_manager.cpp
Normal file
498
engines/titanic/sound/sound_manager.cpp
Normal file
@@ -0,0 +1,498 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/sound_manager.h"
|
||||
#include "titanic/events.h"
|
||||
#include "titanic/titanic.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
const uint LATENCY = 100;
|
||||
const uint CHANNELS_COUNT = 16;
|
||||
|
||||
CSoundManager::CSoundManager() : _musicPercent(75.0), _speechPercent(75.0),
|
||||
_masterPercent(75.0), _parrotPercent(75.0), _handleCtr(1) {
|
||||
}
|
||||
|
||||
uint CSoundManager::getModeVolume(VolumeMode mode) {
|
||||
switch (mode) {
|
||||
case VOL_NORMAL:
|
||||
return (uint)_masterPercent;
|
||||
case VOL_QUIET:
|
||||
return (uint)(_masterPercent * 30 / 100);
|
||||
case VOL_VERY_QUIET:
|
||||
return (uint)(_masterPercent * 15 / 100);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void QSoundManagerSounds::add(CWaveFile *waveFile, int iChannel, CEndTalkerFn endFn, TTtalker *talker) {
|
||||
push_back(new QSoundManagerSound(waveFile, iChannel, endFn, talker));
|
||||
}
|
||||
|
||||
void QSoundManagerSounds::flushChannel(int iChannel) {
|
||||
for (iterator i = begin(); i != end(); ++i) {
|
||||
QSoundManagerSound *item = *i;
|
||||
if (item->_iChannel == iChannel) {
|
||||
if (item->_endFn)
|
||||
item->_endFn(item->_talker);
|
||||
|
||||
remove(item);
|
||||
delete item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundManagerSounds::flushChannel(CWaveFile *waveFile, int iChannel) {
|
||||
for (iterator i = begin(); i != end(); ++i) {
|
||||
QSoundManagerSound *item = *i;
|
||||
if (item->_waveFile->isLoaded() && item->_iChannel == iChannel) {
|
||||
if (item->_endFn)
|
||||
item->_endFn(item->_talker);
|
||||
|
||||
remove(item);
|
||||
delete item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QSoundManagerSounds::contains(const CWaveFile *waveFile) const {
|
||||
for (const_iterator i = begin(); i != end(); ++i) {
|
||||
const QSoundManagerSound *item = *i;
|
||||
if (item->_waveFile == waveFile)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void QSoundManager::Slot::clear() {
|
||||
_waveFile = nullptr;
|
||||
_isTimed = false;
|
||||
_ticks = 0;
|
||||
_channel = -1;
|
||||
_handle = 0;
|
||||
_positioningMode = POSMODE_NONE;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
QSoundManager::QSoundManager(Audio::Mixer *mixer) : CSoundManager(), QMixer(mixer),
|
||||
_field18(0), _field1C(0) {
|
||||
_slots.resize(48);
|
||||
Common::fill(&_channelsVolume[0], &_channelsVolume[16], 0);
|
||||
Common::fill(&_channelsMode[0], &_channelsMode[16], 0);
|
||||
|
||||
qsWaveMixInitEx(QMIXCONFIG(AUDIO_SAMPLING_RATE, CHANNELS_COUNT, LATENCY));
|
||||
qsWaveMixActivate(true);
|
||||
qsWaveMixOpenChannel(0, QMIX_OPENALL);
|
||||
}
|
||||
|
||||
QSoundManager::~QSoundManager() {
|
||||
// Close down the mixer
|
||||
qsWaveMixCloseSession();
|
||||
}
|
||||
|
||||
CWaveFile *QSoundManager::loadSound(const CString &name) {
|
||||
CWaveFile *waveFile = new CWaveFile(_mixer);
|
||||
|
||||
// Try to load the specified sound
|
||||
if (!waveFile->loadSound(name)) {
|
||||
delete waveFile;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return waveFile;
|
||||
}
|
||||
|
||||
CWaveFile *QSoundManager::loadSpeech(CDialogueFile *dialogueFile, int speechId) {
|
||||
CWaveFile *waveFile = new CWaveFile(_mixer);
|
||||
|
||||
// Try to load the specified sound
|
||||
if (!waveFile->loadSpeech(dialogueFile, speechId)) {
|
||||
delete waveFile;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return waveFile;
|
||||
}
|
||||
|
||||
CWaveFile *QSoundManager::loadMusic(const CString &name) {
|
||||
CWaveFile *waveFile = new CWaveFile(_mixer);
|
||||
|
||||
// Try to load the specified sound
|
||||
if (!waveFile->loadMusic(name)) {
|
||||
delete waveFile;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return waveFile;
|
||||
}
|
||||
|
||||
CWaveFile *QSoundManager::loadMusic(CAudioBuffer *buffer, DisposeAfterUse::Flag disposeAfterUse) {
|
||||
CWaveFile *waveFile = new CWaveFile(_mixer);
|
||||
|
||||
// Try to load the specified audio buffer
|
||||
if (!waveFile->loadMusic(buffer, disposeAfterUse)) {
|
||||
delete waveFile;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return waveFile;
|
||||
}
|
||||
|
||||
int QSoundManager::playSound(CWaveFile &waveFile, CProximity &prox) {
|
||||
int channel = -1;
|
||||
uint flags = QMIX_CLEARQUEUE;
|
||||
|
||||
if (prox._priorSoundHandle >= 1) {
|
||||
// This sound should only be started after a prior one finishes,
|
||||
// so scan the slots for the specified sound
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
if (_slots[idx]._handle == prox._priorSoundHandle) {
|
||||
channel = _slots[idx]._channel;
|
||||
flags = QMIX_QUEUEWAVE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (channel >= 0 || (channel = resetChannel(prox._channelMode)) != -1) {
|
||||
return playWave(&waveFile, channel, flags, prox);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QSoundManager::stopSound(int handle) {
|
||||
resetChannel(10);
|
||||
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
Slot &slot = _slots[idx];
|
||||
if (slot._handle == handle) {
|
||||
qsWaveMixFlushChannel(slot._channel);
|
||||
_sounds.flushChannel(slot._channel);
|
||||
resetChannel(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundManager::stopChannel(int channel) {
|
||||
int endChannel;
|
||||
switch (channel) {
|
||||
case 0:
|
||||
case 3:
|
||||
endChannel = channel + 3;
|
||||
break;
|
||||
case 6:
|
||||
endChannel = 10;
|
||||
break;
|
||||
case 10:
|
||||
endChannel = 48;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
for (; channel < endChannel; ++channel) {
|
||||
qsWaveMixFlushChannel(channel);
|
||||
_sounds.flushChannel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundManager::setCanFree(int handle) {
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
if (_slots[idx]._handle == handle)
|
||||
_slots[idx]._isTimed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundManager::stopAllChannels() {
|
||||
qsWaveMixFlushChannel(0, QMIX_OPENALL);
|
||||
|
||||
for (int idx = 0; idx < 16; ++idx)
|
||||
_sounds.flushChannel(idx);
|
||||
resetChannel(10);
|
||||
}
|
||||
|
||||
int QSoundManager::resetChannel(int iChannel) {
|
||||
int newChannel = -1;
|
||||
int channelStart = 10;
|
||||
int channelEnd = 16;
|
||||
|
||||
if (iChannel != 10) {
|
||||
qsWaveMixFlushChannel(iChannel);
|
||||
_sounds.flushChannel(iChannel);
|
||||
channelStart = iChannel;
|
||||
channelEnd = iChannel + 1;
|
||||
} else {
|
||||
uint ticks = g_vm->_events->getTicksCount();
|
||||
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
Slot &slot = _slots[idx];
|
||||
if (slot._isTimed && slot._ticks && ticks > slot._ticks) {
|
||||
qsWaveMixFlushChannel(slot._channel);
|
||||
_sounds.flushChannel(slot._channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (iChannel = channelStart; iChannel < channelEnd; ++iChannel) {
|
||||
if (qsWaveMixIsChannelDone(iChannel)) {
|
||||
// Scan through the slots, and reset any slot using the channel
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
Slot &slot = _slots[idx];
|
||||
if (slot._channel == iChannel)
|
||||
slot.clear();
|
||||
}
|
||||
|
||||
// Use the empty channel
|
||||
newChannel = iChannel;
|
||||
}
|
||||
}
|
||||
|
||||
return newChannel;
|
||||
}
|
||||
|
||||
void QSoundManager::setVolume(int handle, uint volume, uint seconds) {
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
Slot &slot = _slots[idx];
|
||||
if (slot._handle == handle) {
|
||||
assert(slot._channel >= 0);
|
||||
_channelsVolume[slot._channel] = volume;
|
||||
updateVolume(slot._channel, seconds * 1000);
|
||||
|
||||
if (!volume) {
|
||||
uint ticks = g_vm->_events->getTicksCount() + seconds * 1000;
|
||||
if (!slot._ticks || ticks >= slot._ticks)
|
||||
slot._ticks = ticks;
|
||||
} else {
|
||||
slot._ticks = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundManager::setVectorPosition(int handle, double x, double y, double z, uint panRate) {
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
Slot &slot = _slots[idx];
|
||||
if (slot._handle == handle) {
|
||||
qsWaveMixSetPanRate(slot._channel, QMIX_USEONCE, panRate);
|
||||
qsWaveMixSetSourcePosition(slot._channel, QMIX_USEONCE, QSVECTOR(x, y, z));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundManager::setPolarPosition(int handle, double range, double azimuth, double elevation, uint panRate) {
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
Slot &slot = _slots[idx];
|
||||
if (slot._handle == handle) {
|
||||
qsWaveMixSetPanRate(slot._channel, QMIX_USEONCE, panRate);
|
||||
qsWaveMixSetPolarPosition(slot._channel, QMIX_USEONCE,
|
||||
QSPOLAR(azimuth, range, elevation));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QSoundManager::isActive(int handle) {
|
||||
resetChannel(10);
|
||||
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
if (_slots[idx]._handle == handle)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QSoundManager::isActive(const CWaveFile *waveFile) {
|
||||
return _sounds.contains(waveFile);
|
||||
}
|
||||
|
||||
void QSoundManager::waveMixPump() {
|
||||
qsWaveMixPump();
|
||||
}
|
||||
|
||||
uint QSoundManager::getLatency() const {
|
||||
return LATENCY;
|
||||
}
|
||||
|
||||
void QSoundManager::setMusicPercent(double percent) {
|
||||
_musicPercent = percent;
|
||||
updateVolumes();
|
||||
}
|
||||
|
||||
void QSoundManager::setSpeechPercent(double percent) {
|
||||
_speechPercent = percent;
|
||||
updateVolumes();
|
||||
}
|
||||
|
||||
void QSoundManager::setMasterPercent(double percent) {
|
||||
_masterPercent = percent;
|
||||
updateVolumes();
|
||||
}
|
||||
|
||||
void QSoundManager::setParrotPercent(double percent) {
|
||||
_parrotPercent = percent;
|
||||
}
|
||||
|
||||
void QSoundManager::setListenerPosition(double posX, double posY, double posZ,
|
||||
double directionX, double directionY, double directionZ, bool stopSounds) {
|
||||
if (stopSounds) {
|
||||
// Stop any running sounds
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
if (_slots[idx]._positioningMode != 0)
|
||||
stopSound(_slots[idx]._handle);
|
||||
}
|
||||
}
|
||||
|
||||
qsWaveMixSetListenerPosition(QSVECTOR(posX, posY, posZ));
|
||||
qsWaveMixSetListenerOrientation(QSVECTOR(directionX, directionY, directionZ),
|
||||
QSVECTOR(0.0, 0.0, -1.0));
|
||||
}
|
||||
|
||||
int QSoundManager::playWave(CWaveFile *waveFile, int iChannel, uint flags, CProximity &prox) {
|
||||
if (!waveFile || !waveFile->isLoaded())
|
||||
return 0;
|
||||
|
||||
prox._channelVolume = CLIP(prox._channelVolume, 0, 100);
|
||||
prox._balance = CLIP(prox._balance, -100, 100);
|
||||
|
||||
int slotIndex = findFreeSlot();
|
||||
if (slotIndex == -1)
|
||||
return -1;
|
||||
|
||||
// Set the volume
|
||||
setChannelVolume(iChannel, prox._channelVolume, prox._channelMode);
|
||||
|
||||
switch (prox._positioningMode) {
|
||||
case POSMODE_POLAR:
|
||||
qsWaveMixSetPolarPosition(iChannel, 8, QSPOLAR(prox._azimuth, prox._range, prox._elevation));
|
||||
qsWaveMixEnableChannel(iChannel, QMIX_CHANNEL_ELEVATION, true);
|
||||
qsWaveMixSetDistanceMapping(iChannel, 8, QMIX_DISTANCES(5.0, 3.0, 1.0));
|
||||
break;
|
||||
|
||||
case POSMODE_VECTOR:
|
||||
qsWaveMixSetSourcePosition(iChannel, 8, QSVECTOR(prox._posX, prox._posY, prox._posZ));
|
||||
qsWaveMixEnableChannel(iChannel, QMIX_CHANNEL_ELEVATION, true);
|
||||
qsWaveMixSetDistanceMapping(iChannel, 8, QMIX_DISTANCES(5.0, 3.0, 1.0));
|
||||
break;
|
||||
|
||||
default:
|
||||
qsWaveMixEnableChannel(iChannel, QMIX_CHANNEL_ELEVATION, true);
|
||||
qsWaveMixSetPolarPosition(iChannel, 8, QSPOLAR(0.0, 1.0, 0.0));
|
||||
break;
|
||||
}
|
||||
|
||||
if (prox._frequencyMultiplier || prox._frequencyAdjust != 1.875) {
|
||||
uint freq = (uint)(waveFile->getFrequency() * prox._frequencyMultiplier);
|
||||
qsWaveMixSetFrequency(iChannel, 8, freq);
|
||||
}
|
||||
|
||||
_sounds.add(waveFile, iChannel, prox._endTalkerFn, prox._talker);
|
||||
|
||||
QMIXPLAYPARAMS playParams;
|
||||
playParams.callback = soundFinished;
|
||||
playParams.dwUser = this;
|
||||
if (!qsWaveMixPlayEx(iChannel, flags, waveFile, prox._repeated ? -1 : 0, playParams)) {
|
||||
Slot &slot = _slots[slotIndex];
|
||||
slot._handle = _handleCtr++;
|
||||
slot._channel = iChannel;
|
||||
slot._waveFile = waveFile;
|
||||
slot._positioningMode = prox._positioningMode;
|
||||
|
||||
return slot._handle;
|
||||
} else {
|
||||
_sounds.flushChannel(waveFile, iChannel);
|
||||
if (prox._disposeAfterUse == DisposeAfterUse::YES)
|
||||
delete waveFile;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void QSoundManager::soundFreed(Audio::SoundHandle &handle) {
|
||||
qsWaveMixFreeWave(handle);
|
||||
}
|
||||
|
||||
void QSoundManager::updateVolume(int channel, uint panRate) {
|
||||
double volume = _channelsVolume[channel] * 327;
|
||||
|
||||
switch (_channelsMode[channel]) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
volume = (_speechPercent * volume) / 100;
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
volume = (75 * volume) / 100;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
volume = (_masterPercent * volume) / 100;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
volume = (_musicPercent * volume) / 100;
|
||||
qsWaveMixSetPanRate(channel, 0, panRate);
|
||||
qsWaveMixSetVolume(channel, 0, (uint)volume);
|
||||
}
|
||||
|
||||
void QSoundManager::updateVolumes() {
|
||||
for (uint idx = 0; idx < CHANNELS_COUNT; ++idx)
|
||||
updateVolume(idx, 250);
|
||||
}
|
||||
|
||||
void QSoundManager::soundFinished(int iChannel, CWaveFile *waveFile, void *soundManager) {
|
||||
static_cast<QSoundManager *>(soundManager)->_sounds.flushChannel(waveFile, iChannel);
|
||||
}
|
||||
|
||||
int QSoundManager::findFreeSlot() {
|
||||
for (uint idx = 0; idx < _slots.size(); ++idx) {
|
||||
if (!_slots[idx]._waveFile)
|
||||
return idx;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void QSoundManager::setChannelVolume(int iChannel, uint volume, uint mode) {
|
||||
_channelsVolume[iChannel] = volume;
|
||||
_channelsMode[iChannel] = mode;
|
||||
updateVolume(iChannel, 250);
|
||||
}
|
||||
|
||||
} // End of namespace Titanic z
|
||||
474
engines/titanic/sound/sound_manager.h
Normal file
474
engines/titanic/sound/sound_manager.h
Normal file
@@ -0,0 +1,474 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_SOUND_MANAGER_H
|
||||
#define TITANIC_SOUND_MANAGER_H
|
||||
|
||||
#include "titanic/core/list.h"
|
||||
#include "titanic/support/simple_file.h"
|
||||
#include "titanic/sound/audio_buffer.h"
|
||||
#include "titanic/sound/proximity.h"
|
||||
#include "titanic/sound/qmixer.h"
|
||||
#include "titanic/sound/wave_file.h"
|
||||
#include "titanic/true_talk/dialogue_file.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum VolumeMode {
|
||||
VOL_NORMAL = -1, VOL_QUIET = -2, VOL_VERY_QUIET = -3, VOL_MUTE = -4
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract interface class for a sound manager
|
||||
*/
|
||||
class CSoundManager {
|
||||
protected:
|
||||
uint _handleCtr;
|
||||
// Old volume levels, deprecated in favor of setting the volumes
|
||||
// directly in the ScummVM mixer
|
||||
double _musicPercent;
|
||||
double _speechPercent;
|
||||
double _masterPercent;
|
||||
double _parrotPercent;
|
||||
public:
|
||||
CSoundManager();
|
||||
virtual ~CSoundManager() {}
|
||||
|
||||
/**
|
||||
* Loads a sound
|
||||
* @param name Name of sound resource
|
||||
* @returns Loaded wave file
|
||||
*/
|
||||
virtual CWaveFile *loadSound(const CString &name) { return nullptr; }
|
||||
|
||||
/**
|
||||
* Loads a speech resource from a dialogue file
|
||||
* @param name Name of sound resource
|
||||
* @returns Loaded wave file
|
||||
*/
|
||||
virtual CWaveFile *loadSpeech(CDialogueFile *dialogueFile, int speechId) { return 0; }
|
||||
|
||||
/**
|
||||
* Loads a music file
|
||||
* @param name Name of music resource
|
||||
* @returns Loaded wave file
|
||||
* @remarks The original only classified music as what's produced in the
|
||||
* music room puzzle. For ScummVM, we've reclassified some wave files that
|
||||
* contain background music as music as well.
|
||||
*/
|
||||
virtual CWaveFile *loadMusic(const CString &name) { return nullptr; }
|
||||
|
||||
/**
|
||||
* Loads a music file from a streaming audio buffer
|
||||
* @param buffer Audio buffer
|
||||
* @returns Loaded wave file
|
||||
*/
|
||||
virtual CWaveFile *loadMusic(CAudioBuffer *buffer, DisposeAfterUse::Flag disposeAfterUse) { return nullptr; }
|
||||
|
||||
/**
|
||||
* Start playing a previously loaded wave file
|
||||
*/
|
||||
virtual int playSound(CWaveFile &waveFile, CProximity &prox) = 0;
|
||||
|
||||
/**
|
||||
* Stop playing the specified sound
|
||||
*/
|
||||
virtual void stopSound(int handle) = 0;
|
||||
|
||||
/**
|
||||
* Stops a designated range of channels
|
||||
*/
|
||||
virtual void stopChannel(int channel) = 0;
|
||||
|
||||
virtual void proc9(int handle) {}
|
||||
|
||||
/**
|
||||
* Stops sounds on all playing channels
|
||||
*/
|
||||
virtual void stopAllChannels() = 0;
|
||||
|
||||
/**
|
||||
* Sets the volume for a sound
|
||||
* @param handle Handle for sound
|
||||
* @param volume New volume
|
||||
* @param seconds Number of seconds to transition to the new volume
|
||||
*/
|
||||
virtual void setVolume(int handle, uint volume, uint seconds) = 0;
|
||||
|
||||
/**
|
||||
* Set the position for a sound
|
||||
* @param handle Handle for sound
|
||||
* @param x x position in metres
|
||||
* @param y y position in metres
|
||||
* @param z z position in metres
|
||||
* @param panRate Rate in milliseconds to transition
|
||||
*/
|
||||
virtual void setVectorPosition(int handle, double x, double y, double z, uint panRate) {}
|
||||
|
||||
/**
|
||||
* Set the position for a sound
|
||||
* @param handle Handle for sound
|
||||
* @param range Range value in metres
|
||||
* @param azimuth Azimuth value in degrees
|
||||
* @param elevation Elevation value in degrees
|
||||
* @param panRate Rate in milliseconds to transition
|
||||
*/
|
||||
virtual void setPolarPosition(int handle, double range, double azimuth, double elevation, uint panRate) {}
|
||||
|
||||
/**
|
||||
* Returns true if the given sound is currently active
|
||||
*/
|
||||
virtual bool isActive(int handle) = 0;
|
||||
|
||||
/**
|
||||
* Returns true if the given sound is currently active
|
||||
*/
|
||||
virtual bool isActive(const CWaveFile *waveFile) { return false; }
|
||||
|
||||
/**
|
||||
* Handles regularly updating the mixer
|
||||
*/
|
||||
virtual void waveMixPump() = 0;
|
||||
|
||||
/**
|
||||
* Returns the movie latency
|
||||
*/
|
||||
virtual uint getLatency() const { return 0; }
|
||||
|
||||
/**
|
||||
* Sets the music volume percent
|
||||
*/
|
||||
virtual void setMusicPercent(double percent) = 0;
|
||||
|
||||
/**
|
||||
* Sets the speech volume percent
|
||||
*/
|
||||
virtual void setSpeechPercent(double percent) = 0;
|
||||
|
||||
/**
|
||||
* Sets the master volume percent
|
||||
*/
|
||||
virtual void setMasterPercent(double percent) = 0;
|
||||
|
||||
/**
|
||||
* Sets the Parrot NPC volume percent
|
||||
*/
|
||||
virtual void setParrotPercent(double percent) = 0;
|
||||
|
||||
/**
|
||||
* Called when a game is about to be loaded
|
||||
*/
|
||||
virtual void preLoad() { stopAllChannels(); }
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) {}
|
||||
|
||||
/**
|
||||
* Called after loading of a game is completed
|
||||
*/
|
||||
virtual void postLoad() {}
|
||||
|
||||
/**
|
||||
* Called when a game is about to be saved
|
||||
*/
|
||||
virtual void preSave() {}
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file) const {}
|
||||
|
||||
/**
|
||||
* Called after saving is complete
|
||||
*/
|
||||
virtual void postSave() {}
|
||||
|
||||
/**
|
||||
* Sets the position and orientation for the listener (player)
|
||||
*/
|
||||
virtual void setListenerPosition(double posX, double posY, double posZ,
|
||||
double directionX, double directionY, double directionZ, bool stopSounds) {}
|
||||
|
||||
/**
|
||||
* Returns the music volume percent
|
||||
*/
|
||||
double getMusicVolume() const { return _musicPercent; }
|
||||
|
||||
/**
|
||||
* Returns the speech volume percent
|
||||
*/
|
||||
double getSpeechVolume() const { return _speechPercent; }
|
||||
|
||||
/**
|
||||
* Returns the parrot volume percent
|
||||
*/
|
||||
double getParrotVolume() const { return _parrotPercent; }
|
||||
|
||||
/**
|
||||
* Gets the volume for a given mode? value
|
||||
*/
|
||||
uint getModeVolume(VolumeMode mode);
|
||||
};
|
||||
|
||||
class QSoundManagerSound : public ListItem {
|
||||
public:
|
||||
CWaveFile *_waveFile;
|
||||
int _iChannel;
|
||||
CEndTalkerFn _endFn;
|
||||
TTtalker *_talker;
|
||||
public:
|
||||
QSoundManagerSound() : ListItem(), _waveFile(nullptr),
|
||||
_iChannel(0), _endFn(nullptr), _talker(nullptr) {}
|
||||
QSoundManagerSound(CWaveFile *waveFile, int iChannel, CEndTalkerFn endFn, TTtalker *talker) :
|
||||
ListItem(), _waveFile(waveFile), _iChannel(iChannel), _endFn(endFn), _talker(talker) {}
|
||||
};
|
||||
|
||||
class QSoundManagerSounds : public List<QSoundManagerSound> {
|
||||
public:
|
||||
/**
|
||||
* Adds a new sound entry to the list
|
||||
*/
|
||||
void add(CWaveFile *waveFile, int iChannel, CEndTalkerFn endFn, TTtalker *talker);
|
||||
|
||||
/**
|
||||
* Flushes a wave file attached to the specified channel
|
||||
*/
|
||||
void flushChannel(int iChannel);
|
||||
|
||||
/**
|
||||
* Flushes a wave file attached to the specified channel
|
||||
*/
|
||||
void flushChannel(CWaveFile *waveFile, int iChannel);
|
||||
|
||||
/**
|
||||
* Returns true if the list contains the specified wave file
|
||||
*/
|
||||
bool contains(const CWaveFile *waveFile) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Concrete sound manager class that handles interfacing with
|
||||
* the QMixer sound mixer class
|
||||
*/
|
||||
class QSoundManager : public CSoundManager, public QMixer {
|
||||
struct Slot {
|
||||
CWaveFile *_waveFile;
|
||||
bool _isTimed;
|
||||
uint _ticks;
|
||||
int _channel;
|
||||
int _handle;
|
||||
PositioningMode _positioningMode;
|
||||
|
||||
Slot() : _waveFile(0), _isTimed(0), _ticks(0), _channel(-1),
|
||||
_handle(0), _positioningMode(POSMODE_NONE) {}
|
||||
void clear();
|
||||
};
|
||||
private:
|
||||
QSoundManagerSounds _sounds;
|
||||
Common::Array<Slot> _slots;
|
||||
uint _channelsVolume[16];
|
||||
int _channelsMode[16];
|
||||
private:
|
||||
/**
|
||||
* Updates the volume for a channel
|
||||
* @param channel Channel to be update
|
||||
* @param panRate Time in milliseconds for change to occur
|
||||
*/
|
||||
void updateVolume(int channel, uint panRate);
|
||||
|
||||
/**
|
||||
* Updates all the volumes
|
||||
*/
|
||||
void updateVolumes();
|
||||
|
||||
/**
|
||||
* Called by the QMixer when a sound finishes playing
|
||||
*/
|
||||
static void soundFinished(int iChannel, CWaveFile *waveFile, void *soundManager);
|
||||
|
||||
/**
|
||||
* Finds the first free slot
|
||||
*/
|
||||
int findFreeSlot();
|
||||
|
||||
/**
|
||||
* Sets a channel volume
|
||||
*/
|
||||
void setChannelVolume(int iChannel, uint volume, uint mode);
|
||||
|
||||
/**
|
||||
* Resets the specified channel and returns a new free one
|
||||
*/
|
||||
int resetChannel(int iChannel);
|
||||
public:
|
||||
int _field18;
|
||||
int _field1C;
|
||||
|
||||
public:
|
||||
QSoundManager(Audio::Mixer *mixer);
|
||||
~QSoundManager() override;
|
||||
|
||||
/**
|
||||
* Loads a sound
|
||||
* @param name Name of sound resource
|
||||
* @returns Loaded wave file
|
||||
*/
|
||||
CWaveFile *loadSound(const CString &name) override;
|
||||
|
||||
/**
|
||||
* Loads a speech resource from a dialogue file
|
||||
* @param name Name of sound resource
|
||||
* @returns Loaded wave file
|
||||
*/
|
||||
CWaveFile *loadSpeech(CDialogueFile *dialogueFile, int speechId) override;
|
||||
|
||||
/**
|
||||
* Loads a music file
|
||||
* @param name Name of music resource
|
||||
* @returns Loaded wave file
|
||||
* @remarks The original only classified music as what's produced in the
|
||||
* music room puzzle. For ScummVM, we've reclassified some wave files that
|
||||
* contain background music as music as well.
|
||||
*/
|
||||
CWaveFile *loadMusic(const CString &name) override;
|
||||
|
||||
/**
|
||||
* Loads a music file from a streaming audio buffer
|
||||
* @param buffer Audio buffer
|
||||
* @returns Loaded wave file
|
||||
*/
|
||||
CWaveFile *loadMusic(CAudioBuffer *buffer, DisposeAfterUse::Flag disposeAfterUse) override;
|
||||
|
||||
/**
|
||||
* Start playing a previously loaded sound resource
|
||||
*/
|
||||
int playSound(CWaveFile &waveFile, CProximity &prox) override;
|
||||
|
||||
/**
|
||||
* Stop playing the specified sound
|
||||
*/
|
||||
void stopSound(int handle) override;
|
||||
|
||||
/**
|
||||
* Stops a designated range of channels
|
||||
*/
|
||||
void stopChannel(int channel) override;
|
||||
|
||||
/**
|
||||
* Flags that a sound can be freed if a timeout is set
|
||||
*/
|
||||
virtual void setCanFree(int handle);
|
||||
|
||||
/**
|
||||
* Stops sounds on all playing channels
|
||||
*/
|
||||
void stopAllChannels() override;
|
||||
|
||||
/**
|
||||
* Sets the volume for a sound
|
||||
* @param handle Handle for sound
|
||||
* @param volume New volume
|
||||
* @param seconds Number of seconds to transition to the new volume
|
||||
*/
|
||||
void setVolume(int handle, uint volume, uint seconds) override;
|
||||
|
||||
/**
|
||||
* Set the position for a sound
|
||||
* @param handle Handle for sound
|
||||
* @param x x position in metres
|
||||
* @param y y position in metres
|
||||
* @param z z position in metres
|
||||
* @param panRate Rate in milliseconds to transition
|
||||
*/
|
||||
void setVectorPosition(int handle, double x, double y, double z, uint panRate) override;
|
||||
|
||||
/**
|
||||
* Set the position for a sound
|
||||
* @param handle Handle for sound
|
||||
* @param range Range value in metres
|
||||
* @param azimuth Azimuth value in degrees
|
||||
* @param elevation Elevation value in degrees
|
||||
* @param panRate Rate in milliseconds to transition
|
||||
*/
|
||||
void setPolarPosition(int handle, double range, double azimuth, double elevation, uint panRate) override;
|
||||
|
||||
/**
|
||||
* Returns true if the given sound is currently active
|
||||
*/
|
||||
bool isActive(int handle) override;
|
||||
|
||||
/**
|
||||
* Returns true if the given sound is currently active
|
||||
*/
|
||||
bool isActive(const CWaveFile *waveFile) override;
|
||||
|
||||
/**
|
||||
* Handles regularly updating the mixer
|
||||
*/
|
||||
void waveMixPump() override;
|
||||
|
||||
/**
|
||||
* Returns the movie latency
|
||||
*/
|
||||
uint getLatency() const override;
|
||||
|
||||
/**
|
||||
* Sets the music volume percent
|
||||
*/
|
||||
void setMusicPercent(double percent) override;
|
||||
|
||||
/**
|
||||
* Sets the speech volume percent
|
||||
*/
|
||||
void setSpeechPercent(double percent) override;
|
||||
|
||||
/**
|
||||
* Sets the master volume percent
|
||||
*/
|
||||
void setMasterPercent(double percent) override;
|
||||
|
||||
/**
|
||||
* Sets the Parrot NPC volume percent
|
||||
*/
|
||||
void setParrotPercent(double percent) override;
|
||||
|
||||
/**
|
||||
* Sets the position and orientation for the listener (player)
|
||||
*/
|
||||
void setListenerPosition(double posX, double posY, double posZ,
|
||||
double directionX, double directionY, double directionZ, bool stopSounds) override;
|
||||
|
||||
/**
|
||||
* Starts a wave file playing
|
||||
*/
|
||||
virtual int playWave(CWaveFile *waveFile, int iChannel, uint flags, CProximity &prox);
|
||||
|
||||
/**
|
||||
* Called when a wave file is freed
|
||||
*/
|
||||
void soundFreed(Audio::SoundHandle &handle);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_QSOUND_MANAGER_H */
|
||||
166
engines/titanic/sound/titania_speech.cpp
Normal file
166
engines/titanic/sound/titania_speech.cpp
Normal file
@@ -0,0 +1,166 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/titania_speech.h"
|
||||
#include "titanic/translation.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CTitaniaSpeech, CGameObject)
|
||||
ON_MESSAGE(ActMsg)
|
||||
ON_MESSAGE(MovieEndMsg)
|
||||
ON_MESSAGE(MovieFrameMsg)
|
||||
ON_MESSAGE(TimerMsg)
|
||||
ON_MESSAGE(EnterRoomMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CTitaniaSpeech::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_actionNum, indent);
|
||||
file->writeNumberLine(_backgroundFrame, indent);
|
||||
|
||||
CGameObject::save(file, indent);
|
||||
}
|
||||
|
||||
void CTitaniaSpeech::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_actionNum = file->readNumber();
|
||||
_backgroundFrame = file->readNumber();
|
||||
|
||||
CGameObject::load(file);
|
||||
}
|
||||
|
||||
bool CTitaniaSpeech::ActMsg(CActMsg *msg) {
|
||||
CSetFrameMsg frameMsg;
|
||||
CVisibleMsg visibleMsg;
|
||||
CActMsg actMsg;
|
||||
|
||||
if (msg->_action == "TitaniaSpeech") {
|
||||
CProximity prox(Audio::Mixer::kSpeechSoundType);
|
||||
switch (_actionNum) {
|
||||
case 1:
|
||||
loadSound(TRANSLATE("a#12.wav", "a#0.wav"));
|
||||
sleep(1000);
|
||||
playMovie(TRANSLATE(0, 584), TRANSLATE(187, 761),
|
||||
MOVIE_WAIT_FOR_FINISH | MOVIE_NOTIFY_OBJECT);
|
||||
if (g_language == Common::EN_ANY) {
|
||||
movieSetPlaying(true);
|
||||
movieEvent(0);
|
||||
} else {
|
||||
playSound("a#0.wav", prox);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
loadSound(TRANSLATE("a#11.wav", "a#4.wav"));
|
||||
addTimer(0);
|
||||
startAnimTimer("Para2", 300);
|
||||
addTimer(6000);
|
||||
addTimer(12000);
|
||||
addTimer(18000);
|
||||
addTimer(24000);
|
||||
startAnimTimer("NextPara", TRANSLATE(30000, 33000));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
visibleMsg._visible = false;
|
||||
visibleMsg.execute("TitaniaStillControl");
|
||||
loadSound(TRANSLATE("a#10.wav", "a#2.wav"));
|
||||
playMovie(585, TRANSLATE(706, 748), MOVIE_WAIT_FOR_FINISH | MOVIE_NOTIFY_OBJECT);
|
||||
playSound(TRANSLATE("a#10.wav", "a#2.wav"), prox);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
visibleMsg._visible = false;
|
||||
visibleMsg.execute("TitaniaStillControl");
|
||||
loadSound(TRANSLATE("a#9.wav", "a#3.wav"));
|
||||
playMovie(707, 905, MOVIE_WAIT_FOR_FINISH | MOVIE_NOTIFY_OBJECT);
|
||||
playSound(TRANSLATE("a#9.wav", "a#3.wav"), prox);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
visibleMsg._visible = false;
|
||||
visibleMsg.execute("TitaniaStillControl");
|
||||
loadSound(TRANSLATE("a#8.wav", "a#1.wav"));
|
||||
playMovie(906, TRANSLATE(938, 943), MOVIE_WAIT_FOR_FINISH | MOVIE_NOTIFY_OBJECT);
|
||||
playSound(TRANSLATE("a#8.wav", "a#1.wav"), prox);
|
||||
break;
|
||||
|
||||
default:
|
||||
sleep(3000);
|
||||
actMsg._action = "SleepTitania";
|
||||
actMsg.execute("TitaniaControl");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTitaniaSpeech::MovieEndMsg(CMovieEndMsg *msg) {
|
||||
if (_actionNum == 5) {
|
||||
startAnimTimer("NextPara", 0);
|
||||
} else {
|
||||
if (_actionNum != 1)
|
||||
addTimer(0);
|
||||
startAnimTimer("NextPara", 3000);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTitaniaSpeech::MovieFrameMsg(CMovieFrameMsg *msg) {
|
||||
int frame = getMovieFrame();
|
||||
if (frame == 0) {
|
||||
CProximity prox(Audio::Mixer::kSpeechSoundType);
|
||||
playSound(TRANSLATE("a#12.wav", "a#0.wav"), prox);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTitaniaSpeech::TimerMsg(CTimerMsg *msg) {
|
||||
CSetFrameMsg frameMsg;
|
||||
CVisibleMsg visibleMsg;
|
||||
CActMsg actMsg("TitaniaSpeech");
|
||||
|
||||
if (msg->_action == "NextPara") {
|
||||
visibleMsg.execute("TitaniaStillControl");
|
||||
++_actionNum;
|
||||
actMsg.execute(this);
|
||||
} else if (msg->_action == "Para2") {
|
||||
CProximity prox(Audio::Mixer::kSpeechSoundType);
|
||||
playSound(TRANSLATE("a#11.wav", "a#4.wav"), prox);
|
||||
} else {
|
||||
frameMsg._frameNumber = _backgroundFrame++;
|
||||
frameMsg.execute("TitaniaStillControl");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CTitaniaSpeech::EnterRoomMsg(CEnterRoomMsg *msg) {
|
||||
CActMsg actMsg("Disable");
|
||||
actMsg.execute("ShipAnnouncements");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
57
engines/titanic/sound/titania_speech.h
Normal file
57
engines/titanic/sound/titania_speech.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_TITANIA_SPEECH_H
|
||||
#define TITANIC_TITANIA_SPEECH_H
|
||||
|
||||
#include "titanic/core/game_object.h"
|
||||
#include "titanic/messages/messages.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CTitaniaSpeech : public CGameObject {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool ActMsg(CActMsg *msg);
|
||||
bool MovieEndMsg(CMovieEndMsg *msg);
|
||||
bool MovieFrameMsg(CMovieFrameMsg *msg);
|
||||
bool TimerMsg(CTimerMsg *msg);
|
||||
bool EnterRoomMsg(CEnterRoomMsg *msg);
|
||||
private:
|
||||
int _actionNum;
|
||||
int _backgroundFrame;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CTitaniaSpeech() : CGameObject(), _actionNum(1), _backgroundFrame(0) {}
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_TITANIA_SPEECH_H */
|
||||
60
engines/titanic/sound/trigger_auto_music_player.cpp
Normal file
60
engines/titanic/sound/trigger_auto_music_player.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/trigger_auto_music_player.h"
|
||||
#include "titanic/sound/auto_music_player.h"
|
||||
#include "titanic/core/room_item.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CTriggerAutoMusicPlayer, CGameObject)
|
||||
ON_MESSAGE(TriggerAutoMusicPlayerMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CTriggerAutoMusicPlayer::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeQuotedLine(_roomName, indent);
|
||||
CGameObject::save(file, indent);
|
||||
}
|
||||
|
||||
void CTriggerAutoMusicPlayer::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_roomName = file->readString();
|
||||
CGameObject::load(file);
|
||||
}
|
||||
|
||||
bool CTriggerAutoMusicPlayer::TriggerAutoMusicPlayerMsg(CTriggerAutoMusicPlayerMsg *msg) {
|
||||
CRoomItem *room1 = msg->_value == 1 ? locateRoom(_roomName) : findRoom();
|
||||
CRoomItem *room2 = msg->_value == 2 ? locateRoom(_roomName) : findRoom();
|
||||
|
||||
CChangeMusicMsg changeMsg;
|
||||
changeMsg._action = MUSIC_STOP;
|
||||
changeMsg.execute(room1, CAutoMusicPlayer::_type,
|
||||
MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN);
|
||||
|
||||
changeMsg._action = MUSIC_START;
|
||||
changeMsg.execute(room2, CAutoMusicPlayer::_type,
|
||||
MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
50
engines/titanic/sound/trigger_auto_music_player.h
Normal file
50
engines/titanic/sound/trigger_auto_music_player.h
Normal file
@@ -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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_TRIGGER_AUTO_MUSIC_PLAYER_H
|
||||
#define TITANIC_TRIGGER_AUTO_MUSIC_PLAYER_H
|
||||
|
||||
#include "titanic/core/game_object.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CTriggerAutoMusicPlayer : public CGameObject {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool TriggerAutoMusicPlayerMsg(CTriggerAutoMusicPlayerMsg *msg);
|
||||
protected:
|
||||
CString _roomName;
|
||||
public:
|
||||
CLASSDEF;
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_TRIGGER_AUTO_MUSIC_PLAYER_H */
|
||||
83
engines/titanic/sound/view_auto_sound_player.cpp
Normal file
83
engines/titanic/sound/view_auto_sound_player.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/view_auto_sound_player.h"
|
||||
#include "titanic/sound/auto_music_player.h"
|
||||
#include "titanic/core/room_item.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CViewAutoSoundPlayer, CAutoSoundPlayer)
|
||||
ON_MESSAGE(EnterViewMsg)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CViewAutoSoundPlayer::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_enabled, indent);
|
||||
CAutoSoundPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CViewAutoSoundPlayer::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_enabled = file->readNumber();
|
||||
CAutoSoundPlayer::load(file);
|
||||
}
|
||||
|
||||
bool CViewAutoSoundPlayer::EnterViewMsg(CEnterViewMsg *msg) {
|
||||
CViewItem *view = findView();
|
||||
CRoomItem *room = findRoom();
|
||||
|
||||
if (view == msg->_newView) {
|
||||
CTurnOn onMsg;
|
||||
onMsg.execute(this);
|
||||
|
||||
if (_enabled) {
|
||||
CChangeMusicMsg changeMsg;
|
||||
changeMsg._action = MUSIC_STOP;
|
||||
changeMsg.execute(room, CAutoMusicPlayer::_type,
|
||||
MSGFLAG_CLASS_DEF |MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CViewAutoSoundPlayer::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
CViewItem *view = findView();
|
||||
CRoomItem *room = findRoom();
|
||||
|
||||
if (view == msg->_oldView) {
|
||||
CTurnOff offMsg;
|
||||
offMsg.execute(this);
|
||||
|
||||
if (_enabled) {
|
||||
CChangeMusicMsg changeMsg;
|
||||
changeMsg._action = MUSIC_START;
|
||||
changeMsg.execute(room, CAutoMusicPlayer::_type,
|
||||
MSGFLAG_CLASS_DEF | MSGFLAG_BREAK_IF_HANDLED | MSGFLAG_SCAN);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
52
engines/titanic/sound/view_auto_sound_player.h
Normal file
52
engines/titanic/sound/view_auto_sound_player.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_VIEW_AUTO_SOUND_PLAYER_H
|
||||
#define TITANIC_VIEW_AUTO_SOUND_PLAYER_H
|
||||
|
||||
#include "titanic/sound/auto_sound_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CViewAutoSoundPlayer : public CAutoSoundPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool EnterViewMsg(CEnterViewMsg *msg);
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
private:
|
||||
bool _enabled;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CViewAutoSoundPlayer() : CAutoSoundPlayer(), _enabled(false) {}
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_VIEW_AUTO_SOUND_PLAYER_H */
|
||||
57
engines/titanic/sound/view_toggles_other_music.cpp
Normal file
57
engines/titanic/sound/view_toggles_other_music.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/view_toggles_other_music.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
BEGIN_MESSAGE_MAP(CViewTogglesOtherMusic, CEnterViewTogglesOtherMusic)
|
||||
ON_MESSAGE(LeaveViewMsg)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
CViewTogglesOtherMusic::CViewTogglesOtherMusic() :
|
||||
CEnterViewTogglesOtherMusic(), _value(1) {
|
||||
}
|
||||
|
||||
void CViewTogglesOtherMusic::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeNumberLine(_value, indent);
|
||||
|
||||
CEnterViewTogglesOtherMusic::save(file, indent);
|
||||
}
|
||||
|
||||
void CViewTogglesOtherMusic::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_value = file->readNumber();
|
||||
|
||||
CEnterViewTogglesOtherMusic::load(file);
|
||||
}
|
||||
|
||||
bool CViewTogglesOtherMusic::LeaveViewMsg(CLeaveViewMsg *msg) {
|
||||
if (msg->_oldView == findView()) {
|
||||
CTriggerAutoMusicPlayerMsg playerMsg(_value);
|
||||
playerMsg.execute(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
51
engines/titanic/sound/view_toggles_other_music.h
Normal file
51
engines/titanic/sound/view_toggles_other_music.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_VIEW_TOGGLES_OTHER_MUSIC_H
|
||||
#define TITANIC_VIEW_TOGGLES_OTHER_MUSIC_H
|
||||
|
||||
#include "titanic/sound/enter_view_toggles_other_music.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CViewTogglesOtherMusic : public CEnterViewTogglesOtherMusic {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
bool LeaveViewMsg(CLeaveViewMsg *msg);
|
||||
private:
|
||||
int _value;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CViewTogglesOtherMusic();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_VIEW_TOGGLES_OTHER_MUSIC_H */
|
||||
55
engines/titanic/sound/water_lapping_sounds.cpp
Normal file
55
engines/titanic/sound/water_lapping_sounds.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/sound/water_lapping_sounds.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
EMPTY_MESSAGE_MAP(CWaterLappingSounds, CRoomAutoSoundPlayer);
|
||||
|
||||
CWaterLappingSounds::CWaterLappingSounds() : CRoomAutoSoundPlayer(),
|
||||
_value(0) {
|
||||
_filename = "z#217.wav";
|
||||
_repeated = false;
|
||||
_startSeconds = 0;
|
||||
}
|
||||
|
||||
void CWaterLappingSounds::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(1, indent);
|
||||
file->writeQuotedLine(_filename, indent);
|
||||
file->writeNumberLine(_repeated, indent);
|
||||
file->writeNumberLine(_startSeconds, indent);
|
||||
file->writeNumberLine(_value, indent);
|
||||
|
||||
CRoomAutoSoundPlayer::save(file, indent);
|
||||
}
|
||||
|
||||
void CWaterLappingSounds::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
_filename = file->readString();
|
||||
_repeated = file->readNumber();
|
||||
_startSeconds = file->readNumber();
|
||||
_value = file->readNumber();
|
||||
|
||||
CRoomAutoSoundPlayer::load(file);
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
50
engines/titanic/sound/water_lapping_sounds.h
Normal file
50
engines/titanic/sound/water_lapping_sounds.h
Normal file
@@ -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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_WATER_LAPPING_SOUNDS_H
|
||||
#define TITANIC_WATER_LAPPING_SOUNDS_H
|
||||
|
||||
#include "titanic/sound/room_auto_sound_player.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
class CWaterLappingSounds : public CRoomAutoSoundPlayer {
|
||||
DECLARE_MESSAGE_MAP;
|
||||
public:
|
||||
int _value;
|
||||
public:
|
||||
CLASSDEF;
|
||||
CWaterLappingSounds();
|
||||
|
||||
/**
|
||||
* Save the data for the class to file
|
||||
*/
|
||||
void save(SimpleFile *file, int indent) override;
|
||||
|
||||
/**
|
||||
* Load the data for the class from file
|
||||
*/
|
||||
void load(SimpleFile *file) override;
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_WATER_LAPPING_SOUNDS_H */
|
||||
212
engines/titanic/sound/wave_file.cpp
Normal file
212
engines/titanic/sound/wave_file.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "audio/decoders/raw.h"
|
||||
#include "audio/decoders/wave.h"
|
||||
#include "audio/decoders/wave_types.h"
|
||||
#include "common/memstream.h"
|
||||
#include "titanic/sound/wave_file.h"
|
||||
#include "titanic/sound/sound_manager.h"
|
||||
#include "titanic/support/simple_file.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
/**
|
||||
* This creates a ScummVM audio stream around a CAudioBuffer buffer,
|
||||
* allowing for streaming audio output for the music room music
|
||||
*/
|
||||
class AudioBufferStream : public Audio::SeekableAudioStream {
|
||||
private:
|
||||
CAudioBuffer *_audioBuffer;
|
||||
public:
|
||||
AudioBufferStream(CAudioBuffer *audioBuffer) : _audioBuffer(audioBuffer) {}
|
||||
|
||||
int readBuffer(int16 *buffer, const int numSamples) override;
|
||||
bool isStereo() const override { return false; }
|
||||
bool endOfData() const override;
|
||||
int getRate() const override { return 22050; }
|
||||
Audio::Timestamp getLength() const override { return Audio::Timestamp(); }
|
||||
bool seek(const Audio::Timestamp &where) override { return false; }
|
||||
};
|
||||
|
||||
int AudioBufferStream::readBuffer(int16 *buffer, const int numSamples) {
|
||||
return _audioBuffer->read(buffer, numSamples);
|
||||
}
|
||||
|
||||
bool AudioBufferStream::endOfData() const {
|
||||
return _audioBuffer->isFinished();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
CWaveFile::CWaveFile(Audio::Mixer *mixer) : _mixer(mixer), _pendingAudioStream(nullptr),
|
||||
_waveData(nullptr), _waveSize(0), _dataSize(0), _headerSize(0),
|
||||
_rate(0), _flags(0), _wavType(0), _soundType(Audio::Mixer::kPlainSoundType) {
|
||||
setup();
|
||||
}
|
||||
|
||||
void CWaveFile::setup() {
|
||||
_loadMode = LOADMODE_SCUMMVM;
|
||||
_dataSize = 0;
|
||||
_audioBuffer = nullptr;
|
||||
_disposeAudioBuffer = DisposeAfterUse::NO;
|
||||
_channel = -1;
|
||||
}
|
||||
|
||||
CWaveFile::~CWaveFile() {
|
||||
// Delete any pending audio stream if it wasn't used
|
||||
delete _pendingAudioStream;
|
||||
|
||||
if (_disposeAudioBuffer == DisposeAfterUse::YES && _audioBuffer)
|
||||
delete _audioBuffer;
|
||||
|
||||
free(_waveData);
|
||||
}
|
||||
|
||||
uint CWaveFile::getDurationTicks() const {
|
||||
if (!_rate)
|
||||
return 0;
|
||||
|
||||
// FIXME: The original uses acmStreamSize to calculate
|
||||
// a desired size. Since I have no idea how the system API
|
||||
// method works, for now I'm using a simple ratio of a
|
||||
// sample output to input value
|
||||
double newSize = (double)_dataSize * (1475712.0 / 199836.0);
|
||||
return (uint)(newSize * 1000.0 / _rate);
|
||||
}
|
||||
|
||||
bool CWaveFile::loadSound(const CString &name) {
|
||||
StdCWadFile file;
|
||||
if (!file.open(name))
|
||||
return false;
|
||||
|
||||
Common::SeekableReadStream *stream = file.readStream();
|
||||
uint wavSize = stream->size();
|
||||
byte *data = (byte *)malloc(wavSize);
|
||||
stream->read(data, wavSize);
|
||||
|
||||
load(data, wavSize);
|
||||
_soundType = Audio::Mixer::kSFXSoundType;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWaveFile::loadSpeech(CDialogueFile *dialogueFile, int speechIndex) {
|
||||
DialogueResource *res = dialogueFile->openWaveEntry(speechIndex);
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
byte *data = (byte *)malloc(res->_size);
|
||||
dialogueFile->read(res, data, res->_size);
|
||||
load(data, res->_size);
|
||||
|
||||
_soundType = Audio::Mixer::kSpeechSoundType;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWaveFile::loadMusic(const CString &name) {
|
||||
StdCWadFile file;
|
||||
if (!file.open(name))
|
||||
return false;
|
||||
|
||||
Common::SeekableReadStream *stream = file.readStream();
|
||||
uint wavSize = stream->size();
|
||||
byte *data = new byte[wavSize];
|
||||
stream->read(data, wavSize);
|
||||
delete stream;
|
||||
|
||||
load(data, wavSize);
|
||||
_soundType = Audio::Mixer::kMusicSoundType;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CWaveFile::loadMusic(CAudioBuffer *buffer, DisposeAfterUse::Flag disposeAfterUse) {
|
||||
_audioBuffer = buffer;
|
||||
_disposeAudioBuffer = disposeAfterUse;
|
||||
_loadMode = LOADMODE_AUDIO_BUFFER;
|
||||
|
||||
_pendingAudioStream = new AudioBufferStream(_audioBuffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CWaveFile::load(byte *data, uint dataSize) {
|
||||
_waveData = data;
|
||||
_waveSize = dataSize;
|
||||
|
||||
// Parse the wave header
|
||||
Common::MemoryReadStream wavStream(data, dataSize, DisposeAfterUse::NO);
|
||||
if (!Audio::loadWAVFromStream(wavStream, _dataSize, _rate, _flags, &_wavType))
|
||||
error("Invalid wave file");
|
||||
_headerSize = wavStream.pos();
|
||||
}
|
||||
|
||||
Audio::SeekableAudioStream *CWaveFile::createAudioStream() {
|
||||
Audio::SeekableAudioStream *stream;
|
||||
|
||||
if (_pendingAudioStream) {
|
||||
stream = _pendingAudioStream;
|
||||
_pendingAudioStream = nullptr;
|
||||
} else {
|
||||
// Create a new ScummVM audio stream for the wave file data
|
||||
stream = Audio::makeWAVStream(
|
||||
new Common::MemoryReadStream(_waveData, _waveSize, DisposeAfterUse::NO),
|
||||
DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
_rate = stream->getRate();
|
||||
return stream;
|
||||
}
|
||||
|
||||
|
||||
const int16 *CWaveFile::lock() {
|
||||
switch (_loadMode) {
|
||||
case LOADMODE_SCUMMVM:
|
||||
// Sanity checking that only raw 16-bit LE 22Khz waves can be locked
|
||||
assert(_waveData && _rate == AUDIO_SAMPLING_RATE);
|
||||
assert(_flags == (Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_16BITS));
|
||||
assert(_wavType == Audio::kWaveFormatPCM);
|
||||
|
||||
// Return a pointer to the data section of the wave file
|
||||
return (const int16 *)(_waveData + _headerSize);
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CWaveFile::unlock(const int16 *ptr) {
|
||||
// No implementation needed in ScummVM
|
||||
}
|
||||
|
||||
Audio::SoundHandle CWaveFile::play(int numLoops, byte volume) {
|
||||
Audio::SeekableAudioStream *audioStream = createAudioStream();
|
||||
Audio::SoundHandle handle;
|
||||
|
||||
Audio::AudioStream *stream = audioStream;
|
||||
if (numLoops != 0)
|
||||
stream = new Audio::LoopingAudioStream(audioStream,
|
||||
(numLoops == -1) ? 0 : numLoops);
|
||||
|
||||
_mixer->playStream(_soundType, &handle, stream, -1,
|
||||
volume, 0, DisposeAfterUse::YES);
|
||||
return handle;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
138
engines/titanic/sound/wave_file.h
Normal file
138
engines/titanic/sound/wave_file.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TITANIC_WAVE_FILE_H
|
||||
#define TITANIC_WAVE_FILE_H
|
||||
|
||||
#include "audio/audiostream.h"
|
||||
#include "audio/mixer.h"
|
||||
#include "titanic/sound/audio_buffer.h"
|
||||
#include "titanic/support/string.h"
|
||||
#include "titanic/true_talk/dialogue_file.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
enum LoadMode { LOADMODE_AUDIO_BUFFER = 1, LOADMODE_SCUMMVM = 2 };
|
||||
|
||||
class CWaveFile {
|
||||
private:
|
||||
Audio::Mixer *_mixer;
|
||||
byte *_waveData;
|
||||
int _waveSize;
|
||||
int _dataSize;
|
||||
int _headerSize;
|
||||
int _rate;
|
||||
byte _flags;
|
||||
uint16 _wavType;
|
||||
Audio::SeekableAudioStream *_pendingAudioStream;
|
||||
private:
|
||||
/**
|
||||
* Handles setup of fields shared by the constructors
|
||||
*/
|
||||
void setup();
|
||||
|
||||
/**
|
||||
* Gets passed the raw data for the wave file
|
||||
*/
|
||||
void load(byte *data, uint dataSize);
|
||||
|
||||
/**
|
||||
* Returns a ScummVM Audio Stream for playback purposes
|
||||
*/
|
||||
Audio::SeekableAudioStream *createAudioStream();
|
||||
public:
|
||||
Audio::Mixer::SoundType _soundType;
|
||||
|
||||
LoadMode _loadMode;
|
||||
CAudioBuffer *_audioBuffer;
|
||||
DisposeAfterUse::Flag _disposeAudioBuffer;
|
||||
int _channel;
|
||||
public:
|
||||
CWaveFile(Audio::Mixer *mixer);
|
||||
~CWaveFile();
|
||||
|
||||
/**
|
||||
* Returns the duration of the wave file
|
||||
* @returns Total ticks. Not really sure how ticks
|
||||
* map to real time
|
||||
*/
|
||||
uint getDurationTicks() const;
|
||||
|
||||
/**
|
||||
* Return the size of the wave file
|
||||
*/
|
||||
uint size() const { return _dataSize; }
|
||||
|
||||
/**
|
||||
* Tries to load the specified wave file sound
|
||||
*/
|
||||
bool loadSound(const CString &name);
|
||||
|
||||
/**
|
||||
* Tries to load speech from a specified dialogue file
|
||||
*/
|
||||
bool loadSpeech(CDialogueFile *dialogueFile, int speechIndex);
|
||||
|
||||
/**
|
||||
* Tries to load the specified music wave file
|
||||
*/
|
||||
bool loadMusic(const CString &name);
|
||||
|
||||
/**
|
||||
* Tries to load the specified audio buffer
|
||||
*/
|
||||
bool loadMusic(CAudioBuffer *buffer, DisposeAfterUse::Flag disposeAfterUse);
|
||||
|
||||
/**
|
||||
* Returns true if the wave file has data loaded
|
||||
*/
|
||||
bool isLoaded() const {
|
||||
return _waveData != nullptr || _pendingAudioStream != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the frequency of the loaded wave file
|
||||
*/
|
||||
uint getFrequency() const { return _rate; }
|
||||
|
||||
/**
|
||||
* Lock sound data for access
|
||||
*/
|
||||
const int16 *lock();
|
||||
|
||||
/**
|
||||
* Unlock sound data after a prior call to lock
|
||||
*/
|
||||
void unlock(const int16 *ptr);
|
||||
|
||||
/**
|
||||
* Plays the wave file
|
||||
* @param numLoops Number of times to loop. 0 for none,
|
||||
* -1 for infinite, and >0 for specified number of times
|
||||
* @param volume Volume to play at
|
||||
* @returns Audio handle for started sound
|
||||
*/
|
||||
Audio::SoundHandle play(int numLoops, byte volume);
|
||||
};
|
||||
|
||||
} // End of namespace Titanic
|
||||
|
||||
#endif /* TITANIC_WAVE_FILE_H */
|
||||
Reference in New Issue
Block a user