diff options
Diffstat (limited to 'engines/sword25/sfx')
-rw-r--r-- | engines/sword25/sfx/soundengine.cpp | 274 | ||||
-rw-r--r-- | engines/sword25/sfx/soundengine.h | 263 | ||||
-rw-r--r-- | engines/sword25/sfx/soundengine_script.cpp | 365 |
3 files changed, 902 insertions, 0 deletions
diff --git a/engines/sword25/sfx/soundengine.cpp b/engines/sword25/sfx/soundengine.cpp new file mode 100644 index 0000000000..c753afd9b9 --- /dev/null +++ b/engines/sword25/sfx/soundengine.cpp @@ -0,0 +1,274 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +/* + * This code is based on Broken Sword 2.5 engine + * + * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer + * + * Licensed under GNU GPL v2 + * + */ + +#define BS_LOG_PREFIX "SOUNDENGINE" + +#include "sword25/sword25.h" +#include "sword25/sfx/soundengine.h" +#include "sword25/package/packagemanager.h" +#include "sword25/kernel/resource.h" + +#include "sound/decoders/vorbis.h" + +namespace Sword25 { + +class SoundResource : public Resource { +public: + SoundResource(const Common::String &fileName) : Resource(fileName, Resource::TYPE_SOUND), _fname(fileName) {} + virtual ~SoundResource() { + debugC(1, kDebugSound, "SoundResource: Unloading file %s", _fname.c_str()); + } + +private: + Common::String _fname; +}; + + +SoundEngine::SoundEngine(Kernel *pKernel) : ResourceService(pKernel) { + if (!registerScriptBindings()) + BS_LOG_ERRORLN("Script bindings could not be registered."); + else + BS_LOGLN("Script bindings registered."); + + _mixer = g_system->getMixer(); + + for (int i = 0; i < SOUND_HANDLES; i++) + _handles[i].type = kFreeHandle; +} + +Service *SoundEngine_CreateObject(Kernel *pKernel) { + return new SoundEngine(pKernel); +} + +bool SoundEngine::init(uint sampleRate, uint channels) { + warning("STUB: SoundEngine::init(%d, %d)", sampleRate, channels); + + return true; +} + +void SoundEngine::update() { +} + +void SoundEngine::setVolume(float volume, SOUND_TYPES type) { + warning("STUB: SoundEngine::setVolume(%f, %d)", volume, type); +} + +float SoundEngine::getVolume(SOUND_TYPES type) { + warning("STUB: SoundEngine::getVolume(%d)", type); + return 0; +} + +void SoundEngine::pauseAll() { + debugC(1, kDebugSound, "SoundEngine::pauseAll()"); + + _mixer->pauseAll(true); +} + +void SoundEngine::resumeAll() { + debugC(1, kDebugSound, "SoundEngine::resumeAll()"); + + _mixer->pauseAll(false); +} + +void SoundEngine::pauseLayer(uint layer) { + warning("STUB: SoundEngine::pauseLayer(%d)", layer); +} + +void SoundEngine::resumeLayer(uint layer) { + warning("STUB: SoundEngine::resumeLayer(%d)", layer); +} + +SndHandle *SoundEngine::getHandle(uint *id) { + + // NOTE: Index 0 means error. Thus we're not using it + for (uint i = 1; i < SOUND_HANDLES; i++) { + if (_handles[i].type != kFreeHandle && !_mixer->isSoundHandleActive(_handles[i].handle)) { + debugC(kDebugSound, 5, "Handle %d has finished playing", i); + _handles[i].type = kFreeHandle; + } + } + + for (uint i = 1; i < SOUND_HANDLES; i++) { + if (_handles[i].type == kFreeHandle) { + debugC(kDebugSound, 5, "Allocated handle %d", i); + if (id) + *id = i; + return &_handles[i]; + } + } + + error("Sound::getHandle(): Too many sound handles"); + + return NULL; +} + +Audio::Mixer::SoundType getType(SoundEngine::SOUND_TYPES type) { + switch (type) { + case SoundEngine::MUSIC: + return Audio::Mixer::kMusicSoundType; + case SoundEngine::SPEECH: + return Audio::Mixer::kSpeechSoundType; + case SoundEngine::SFX: + return Audio::Mixer::kSFXSoundType; + default: + error("Unknown SOUND_TYPE"); + } + + return Audio::Mixer::kPlainSoundType; +} + +bool SoundEngine::playSound(const Common::String &fileName, SOUND_TYPES type, float volume, float pan, bool loop, int loopStart, int loopEnd, uint layer) { + debugC(1, kDebugSound, "SoundEngine::playSound(%s, %d, %f, %f, %d, %d, %d, %d)", fileName.c_str(), type, volume, pan, loop, loopStart, loopEnd, layer); + + playSoundEx(fileName, type, volume, pan, loop, loopStart, loopEnd, layer); + + return true; +} + +uint SoundEngine::playSoundEx(const Common::String &fileName, SOUND_TYPES type, float volume, float pan, bool loop, int loopStart, int loopEnd, uint layer) { + Common::SeekableReadStream *in = Kernel::GetInstance()->GetPackage()->getStream(fileName); + Audio::SeekableAudioStream *stream = Audio::makeVorbisStream(in, DisposeAfterUse::YES); + uint id; + SndHandle *handle = getHandle(&id); + + debugC(1, kDebugSound, "SoundEngine::playSoundEx(%s, %d, %f, %f, %d, %d, %d, %d)", fileName.c_str(), type, volume, pan, loop, loopStart, loopEnd, layer); + + _mixer->playStream(getType(type), &(handle->handle), stream, -1, (byte)(volume * 255), (int8)(pan * 127)); + + return id; +} + +void SoundEngine::setSoundVolume(uint handle, float volume) { + assert(handle < SOUND_HANDLES); + + debugC(1, kDebugSound, "SoundEngine::setSoundVolume(%d, %f)", handle, volume); + + _mixer->setChannelVolume(_handles[handle].handle, (byte)(volume * 255)); +} + +void SoundEngine::setSoundPanning(uint handle, float pan) { + assert(handle < SOUND_HANDLES); + + debugC(1, kDebugSound, "SoundEngine::setSoundPanning(%d, %f)", handle, pan); + + _mixer->setChannelBalance(_handles[handle].handle, (int8)(pan * 127)); +} + +void SoundEngine::pauseSound(uint handle) { + assert(handle < SOUND_HANDLES); + + debugC(1, kDebugSound, "SoundEngine::pauseSound(%d)", handle); + + _mixer->pauseHandle(_handles[handle].handle, true); +} + +void SoundEngine::resumeSound(uint handle) { + assert(handle < SOUND_HANDLES); + + debugC(1, kDebugSound, "SoundEngine::resumeSound(%d)", handle); + + _mixer->pauseHandle(_handles[handle].handle, false); +} + +void SoundEngine::stopSound(uint handle) { + assert(handle < SOUND_HANDLES); + + debugC(1, kDebugSound, "SoundEngine::stopSound(%d)", handle); + + _mixer->stopHandle(_handles[handle].handle); +} + +bool SoundEngine::isSoundPaused(uint handle) { + warning("STUB: SoundEngine::isSoundPaused(%d)", handle); + + return false; +} + +bool SoundEngine::isSoundPlaying(uint handle) { + assert(handle < SOUND_HANDLES); + + debugC(1, kDebugSound, "SoundEngine::isSoundPlaying(%d)", handle); + + return _mixer->isSoundHandleActive(_handles[handle].handle); +} + +float SoundEngine::getSoundVolume(uint handle) { + warning("STUB: SoundEngine::getSoundVolume(%d)", handle); + + return 0; +} + +float SoundEngine::getSoundPanning(uint handle) { + warning("STUB: SoundEngine::getSoundPanning(%d)", handle); + + return 0; +} + +float SoundEngine::getSoundTime(uint handle) { + warning("STUB: SoundEngine::getSoundTime(%d)", handle); + + return 0; +} + +Resource *SoundEngine::loadResource(const Common::String &fileName) { + warning("STUB: SoundEngine::loadResource(%s)", fileName.c_str()); + + return new SoundResource(fileName); +} + +bool SoundEngine::canLoadResource(const Common::String &fileName) { + Common::String fname = fileName; + + debugC(1, kDebugSound, "SoundEngine::canLoadResource(%s)", fileName.c_str()); + + fname.toLowercase(); + + return fname.hasSuffix(".ogg"); +} + + +bool SoundEngine::persist(OutputPersistenceBlock &writer) { + warning("STUB: SoundEngine::persist()"); + + return true; +} + +bool SoundEngine::unpersist(InputPersistenceBlock &reader) { + warning("STUB: SoundEngine::unpersist()"); + + return true; +} + + +} // End of namespace Sword25 diff --git a/engines/sword25/sfx/soundengine.h b/engines/sword25/sfx/soundengine.h new file mode 100644 index 0000000000..81383b12cb --- /dev/null +++ b/engines/sword25/sfx/soundengine.h @@ -0,0 +1,263 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +/* + * This code is based on Broken Sword 2.5 engine + * + * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer + * + * Licensed under GNU GPL v2 + * + */ + +/* + * BS_SoundEngine + * ------------- + * This is the sound engine interface that contains all the methods a sound + * engine must implement. + * Implementations of the sound engine have to be derived from this class. + * It should be noted that a sound engine must maintain a list of all the + * samples it uses, and that these samples should be released when the + * destructor is called. + * + * Autor: Malte Thiesen + */ + +#ifndef SWORD25_SOUNDENGINE_H +#define SWORD25_SOUNDENGINE_H + +#include "sword25/kernel/common.h" +#include "sword25/kernel/resservice.h" +#include "sword25/kernel/persistable.h" + +#include "sound/audiostream.h" +#include "sound/mixer.h" + +namespace Sword25 { + +#define SOUND_HANDLES 32 + +enum sndHandleType { + kFreeHandle, + kEffectHandle, + kVoiceHandle +}; + +struct SndHandle { + Audio::SoundHandle handle; + sndHandleType type; +}; + + +class SoundEngine : public ResourceService, public Persistable { +public: + enum SOUND_TYPES { + MUSIC = 0, + SPEECH = 1, + SFX = 2 + }; + + /** + * The callback function of PlayDynamicSoundEx + * @param UserData User-specified pointer + * @param Data Pointer to the data buffer + * @param DataLength Length of the data to be written in bytes + */ + typedef void (*DynamicSoundReadCallback)(void *UserData, void *Data, uint DataLength); + + SoundEngine(Kernel *pKernel); + ~SoundEngine() {}; + + /** + * Initialises the sound engine + * @param SampleRate Specifies the sample rate to use. + * @param Channels The maximum number of channels. The default is 32. + * @return Returns true on success, otherwise false. + * @remark Calls to other methods may take place only if this + * method was called successfully. + */ + bool init(uint sampleRate, uint channels = 32); + + /** + * Performs a "tick" of the sound engine + * + * This method should be called once per frame. It can be used by implementations + * of the sound engine that are not running in their own thread, or to perform + * additional administrative tasks that are needed. + */ + void update(); + + /** + * Sets the default volume for the different sound types + * @param Volume The default volume level (0 = off, 1 = full volume) + * @param Type The SoundType whose volume is to be changed + */ + void setVolume(float volume, SOUND_TYPES type); + + /** + * Specifies the default volume of different sound types + * @param Type The SoundType + * @return Returns the standard sound volume for the given type + * (0 = off, 1 = full volume). + */ + float getVolume(SOUND_TYPES type); + + /** + * Pauses all the sounds that are playing. + */ + void pauseAll(); + + /** + * Resumes all currently stopped sounds + */ + void resumeAll(); + + /** + * Pauses all sounds of a given layer. + * @param Layer The Sound Layer + */ + void pauseLayer(uint layer); + + /** + * Resumes all the sounds in a layer that was previously stopped with PauseLayer() + * @param Layer The Sound Layer + */ + void resumeLayer(uint layer); + + /** + * Plays a sound + * @param FileName The filename of the sound to be played + * @param Type The type of sound + * @param Volume The volume of the sound (0 = off, 1 = full volume) + * @param Pan Panning (-1 = full left, 1 = right) + * @param Loop Indicates whether the sound should be looped + * @param LoopStart Indicates the starting loop point. If a value less than 0 is passed, the start + * of the sound is used. + * @param LoopEnd Indicates the ending loop point. If a avlue is passed less than 0, the end of + * the sound is used. + * @param Layer The sound layer + * @return Returns true if the playback of the sound was started successfully. + * @remark If more control is needed over the playing, eg. changing the sound parameters + * for Volume and Panning, then PlaySoundEx should be used. + */ + bool playSound(const Common::String &fileName, SOUND_TYPES type, float volume = 1.0f, float pan = 0.0f, bool loop = false, int loopStart = -1, int loopEnd = -1, uint layer = 0); + + /** + * Plays a sound + * @param Type The type of sound + * @param Volume The volume of the sound (0 = off, 1 = full volume) + * @param Pan Panning (-1 = full left, 1 = right) + * @param Loop Indicates whether the sound should be looped + * @param LoopStart Indicates the starting loop point. If a value less than 0 is passed, the start + * of the sound is used. + * @param LoopEnd Indicates the ending loop point. If a avlue is passed less than 0, the end of + * the sound is used. + * @param Layer The sound layer + * @return Returns a handle to the sound. With this handle, the sound can be manipulated during playback. + * @remark If more control is needed over the playing, eg. changing the sound parameters + * for Volume and Panning, then PlaySoundEx should be used. + */ + uint playSoundEx(const Common::String &fileName, SOUND_TYPES type, float volume = 1.0f, float pan = 0.0f, bool loop = false, int loopStart = -1, int loopEnd = -1, uint layer = 0); + + /** + * Sets the volume of a playing sound + * @param Handle The sound handle + * @param Volume The volume of the sound (0 = off, 1 = full volume) + */ + void setSoundVolume(uint handle, float volume); + + /** + * Sets the panning of a playing sound + * @param Handle The sound handle + * @param Pan Panning (-1 = full left, 1 = right) + */ + void setSoundPanning(uint handle, float pan); + + /** + * Pauses a playing sound + * @param Handle The sound handle + */ + void pauseSound(uint handle); + + /** + * Resumes a paused sound + * @param Handle The sound handle + */ + void resumeSound(uint handle); + + /** + * Stops a playing sound + * @param Handle The sound handle + * @remark Calling this method invalidates the passed handle; it can no longer be used. + */ + void stopSound(uint handle); + + /** + * Returns whether a sound is paused + * @param Handle The sound handle + * @return Returns true if the sound is paused, false otherwise. + */ + bool isSoundPaused(uint handle); + + /** + * Returns whether a sound is still playing. + * @param Handle The sound handle + * @return Returns true if the sound is playing, false otherwise. + */ + bool isSoundPlaying(uint handle); + + /** + * Returns the volume of a playing sound (0 = off, 1 = full volume) + */ + float getSoundVolume(uint handle); + + /** + * Returns the panning of a playing sound (-1 = full left, 1 = right) + */ + float getSoundPanning(uint handle); + + /** + * Returns the position within a playing sound in seconds + */ + float getSoundTime(uint handle); + + Resource *loadResource(const Common::String &fileName); + bool canLoadResource(const Common::String &fileName); + + bool persist(OutputPersistenceBlock &writer); + bool unpersist(InputPersistenceBlock &reader); + +private: + bool registerScriptBindings(); + SndHandle *getHandle(uint *id); + +private: + Audio::Mixer *_mixer; + SndHandle _handles[SOUND_HANDLES]; +}; + +} // End of namespace Sword25 + +#endif diff --git a/engines/sword25/sfx/soundengine_script.cpp b/engines/sword25/sfx/soundengine_script.cpp new file mode 100644 index 0000000000..2808296799 --- /dev/null +++ b/engines/sword25/sfx/soundengine_script.cpp @@ -0,0 +1,365 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +/* + * This code is based on Broken Sword 2.5 engine + * + * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer + * + * Licensed under GNU GPL v2 + * + */ + +// ----------------------------------------------------------------------------- +// Includes +// ----------------------------------------------------------------------------- + +#include "sword25/kernel/common.h" +#include "sword25/kernel/kernel.h" +#include "sword25/script/script.h" +#include "sword25/script/luabindhelper.h" + +#include "sword25/sfx/soundengine.h" + +namespace Sword25 { + +static int init(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + if (lua_gettop(L) == 0) + lua_pushbooleancpp(L, pSfx->init(44100, 32)); + else if (lua_gettop(L) == 1) + lua_pushbooleancpp(L, pSfx->init(static_cast<uint>(luaL_checknumber(L, 1)), 32)); + else + lua_pushbooleancpp(L, pSfx->init(static_cast<uint>(luaL_checknumber(L, 1)), static_cast<uint>(luaL_checknumber(L, 2)))); + + return 1; +} + +static int update(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->update(); + + return 0; +} + +static int setVolume(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->setVolume(static_cast<float>(luaL_checknumber(L, 1)), + static_cast<SoundEngine::SOUND_TYPES>(static_cast<uint>(luaL_checknumber(L, 2)))); + + return 0; +} + +static int getVolume(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + lua_pushnumber(L, pSfx->getVolume(static_cast<SoundEngine::SOUND_TYPES>(static_cast<uint>(luaL_checknumber(L, 1))))); + + return 1; +} + +static int pauseAll(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->pauseAll(); + + return 0; +} + +static int resumeAll(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->resumeAll(); + + return 0; +} + +static int pauseLayer(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->pauseLayer(static_cast<int>(luaL_checknumber(L, 1))); + + return 0; +} + +static int resumeLayer(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->resumeLayer(static_cast<int>(luaL_checknumber(L, 1))); + + return 0; +} + +static void processPlayParams(lua_State *L, Common::String &fileName, SoundEngine::SOUND_TYPES &type, float &volume, float &pan, bool &loop, int &loopStart, int &loopEnd, uint &layer) { + fileName = luaL_checkstring(L, 1); + + type = static_cast<SoundEngine::SOUND_TYPES>(static_cast<uint>(luaL_checknumber(L, 2))); + + if (lua_gettop(L) < 3 || lua_isnil(L, 3)) + volume = 1.0f; + else + volume = static_cast<float>(luaL_checknumber(L, 3)); + + if (lua_gettop(L) < 4 || lua_isnil(L, 4)) + pan = 0.0f; + else + pan = static_cast<float>(luaL_checknumber(L, 4)); + + if (lua_gettop(L) < 5 || lua_isnil(L, 5)) + loop = false; + else + loop = lua_tobooleancpp(L, 5); + + if (lua_gettop(L) < 6 || lua_isnil(L, 6)) + loopStart = -1; + else + loopStart = static_cast<int>(luaL_checknumber(L, 6)); + + if (lua_gettop(L) < 7 || lua_isnil(L, 7)) + loopEnd = -1; + else + loopEnd = static_cast<int>(luaL_checknumber(L, 7)); + + if (lua_gettop(L) < 8 || lua_isnil(L, 8)) + layer = 0; + else + layer = static_cast<uint>(luaL_checknumber(L, 8)); +} + +static int playSound(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + Common::String fileName; + SoundEngine::SOUND_TYPES type; + float volume; + float pan; + bool loop; + int loopStart; + int loopEnd; + uint layer; + processPlayParams(L, fileName, type, volume, pan, loop, loopStart, loopEnd, layer); + + lua_pushbooleancpp(L, pSfx->playSound(fileName, type, volume, pan, loop, loopStart, loopEnd, layer)); + + return 1; +} + +static int playSoundEx(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + Common::String fileName; + SoundEngine::SOUND_TYPES type; + float volume; + float pan; + bool loop; + int loopStart; + int loopEnd; + uint layer; + processPlayParams(L, fileName, type, volume, pan, loop, loopStart, loopEnd, layer); + + lua_pushnumber(L, pSfx->playSoundEx(fileName, type, volume, pan, loop, loopStart, loopEnd, layer)); + + return 1; +} + +static int setSoundVolume(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->setSoundVolume(static_cast<uint>(luaL_checknumber(L, 1)), static_cast<float>(luaL_checknumber(L, 2))); + + return 0; +} + +static int setSoundPanning(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->setSoundPanning(static_cast<uint>(luaL_checknumber(L, 1)), static_cast<float>(luaL_checknumber(L, 2))); + + return 0; +} + +static int pauseSound(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->pauseSound(static_cast<uint>(luaL_checknumber(L, 1))); + + return 0; +} + +static int resumeSound(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->resumeSound(static_cast<uint>(luaL_checknumber(L, 1))); + + return 0; +} + +static int stopSound(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + pSfx->stopSound(static_cast<uint>(luaL_checknumber(L, 1))); + + return 0; +} + +static int isSoundPaused(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + lua_pushbooleancpp(L, pSfx->isSoundPaused(static_cast<uint>(luaL_checknumber(L, 1)))); + + return 1; +} + +static int isSoundPlaying(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + lua_pushbooleancpp(L, pSfx->isSoundPlaying(static_cast<uint>(luaL_checknumber(L, 1)))); + + return 1; +} + +static int getSoundVolume(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + lua_pushnumber(L, pSfx->getSoundVolume(static_cast<uint>(luaL_checknumber(L, 1)))); + + return 1; +} + +static int getSoundPanning(lua_State *L) { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + SoundEngine *pSfx = static_cast<SoundEngine *>(Kernel::GetInstance()->GetService("sfx")); + BS_ASSERT(pSfx); + + lua_pushnumber(L, pSfx->getSoundPanning(static_cast<uint>(luaL_checknumber(L, 1)))); + + return 1; +} + +static const char *SFX_LIBRARY_NAME = "Sfx"; + +static const luaL_reg SFX_FUNCTIONS[] = { + {"Init", init}, + {"Update", update}, + {"__SetVolume", setVolume}, + {"__GetVolume", getVolume}, + {"PauseAll", pauseAll}, + {"ResumeAll", resumeAll}, + {"PauseLayer", pauseLayer}, + {"ResumeLayer", resumeLayer}, + {"__PlaySound", playSound}, + {"__PlaySoundEx", playSoundEx}, + {"__SetSoundVolume", setSoundVolume}, + {"__SetSoundPanning", setSoundPanning}, + {"__PauseSound", pauseSound}, + {"__ResumeSound", resumeSound}, + {"__StopSound", stopSound}, + {"__IsSoundPaused", isSoundPaused}, + {"__IsSoundPlaying", isSoundPlaying}, + {"__GetSoundVolume", getSoundVolume}, + {"__GetSoundPanning", getSoundPanning}, + {0, 0} +}; + +static const lua_constant_reg SFX_CONSTANTS[] = { + {"MUSIC", SoundEngine::MUSIC}, + {"SPEECH", SoundEngine::SPEECH}, + {"SFX", SoundEngine::SFX}, + {0, 0} +}; + +bool SoundEngine::registerScriptBindings() { + Kernel *pKernel = Kernel::GetInstance(); + BS_ASSERT(pKernel); + ScriptEngine *pScript = static_cast<ScriptEngine *>(pKernel->GetService("script")); + BS_ASSERT(pScript); + lua_State *L = static_cast<lua_State *>(pScript->getScriptObject()); + BS_ASSERT(L); + + if (!LuaBindhelper::addFunctionsToLib(L, SFX_LIBRARY_NAME, SFX_FUNCTIONS)) return false; + if (!LuaBindhelper::addConstantsToLib(L, SFX_LIBRARY_NAME, SFX_CONSTANTS)) return false; + + return true; +} + +} // End of namespace Sword25 |