New sound system & removed miles
This commit is contained in:
8421
extern/include/MSS.H
vendored
8421
extern/include/MSS.H
vendored
File diff suppressed because it is too large
Load Diff
2
extern/include/miniaudio.c
vendored
Normal file
2
extern/include/miniaudio.c
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#define MINIAUDIO_IMPLEMENTATION
|
||||||
|
#include "miniaudio.h"
|
||||||
93468
extern/include/miniaudio.h
vendored
Normal file
93468
extern/include/miniaudio.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
extern/library/CMakeLists.txt
vendored
1
extern/library/CMakeLists.txt
vendored
@@ -1,6 +1,5 @@
|
|||||||
add_subdirectory(DirectX)
|
add_subdirectory(DirectX)
|
||||||
add_subdirectory(Granny)
|
add_subdirectory(Granny)
|
||||||
add_subdirectory(MilesSoundSystem)
|
|
||||||
add_subdirectory(Python)
|
add_subdirectory(Python)
|
||||||
add_subdirectory(SpeedTree)
|
add_subdirectory(SpeedTree)
|
||||||
add_subdirectory(WebView)
|
add_subdirectory(WebView)
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
add_library(MilesSoundSystem STATIC IMPORTED GLOBAL)
|
|
||||||
|
|
||||||
set_target_properties(MilesSoundSystem PROPERTIES
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/extern/include"
|
|
||||||
IMPORTED_LOCATION "${CMAKE_CURRENT_LIST_DIR}/mss64.lib"
|
|
||||||
)
|
|
||||||
BIN
extern/library/MilesSoundSystem/mss64.lib
vendored
BIN
extern/library/MilesSoundSystem/mss64.lib
vendored
Binary file not shown.
9
src/AudioLib/CMakeLists.txt
Normal file
9
src/AudioLib/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
file(GLOB_RECURSE FILE_SOURCES "*.h" "*.c" "*.cpp")
|
||||||
|
|
||||||
|
add_library(AudioLib STATIC ${FILE_SOURCES})
|
||||||
|
|
||||||
|
target_link_libraries(AudioLib
|
||||||
|
lzo2
|
||||||
|
)
|
||||||
|
|
||||||
|
GroupSourcesByFolder(AudioLib)
|
||||||
175
src/AudioLib/MaSoundInstance.cpp
Normal file
175
src/AudioLib/MaSoundInstance.cpp
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "MaSoundInstance.h"
|
||||||
|
|
||||||
|
#include <miniaudio.c>
|
||||||
|
|
||||||
|
bool MaSoundInstance::InitFromBuffer(ma_engine& engine, const std::vector<uint8_t>& buffer, const std::string& identity)
|
||||||
|
{
|
||||||
|
if (!m_Initialized)
|
||||||
|
{
|
||||||
|
ma_decoder_config decoderConfig = ma_decoder_config_init_default();
|
||||||
|
ma_result result = ma_decoder_init_memory(buffer.data(), buffer.size(),
|
||||||
|
&decoderConfig, &m_Decoder);
|
||||||
|
if (!MD_ASSERT(result == MA_SUCCESS))
|
||||||
|
{
|
||||||
|
TraceError("Failed to initialize decoder memory.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ma_sound_config soundConfig = ma_sound_config_init();
|
||||||
|
soundConfig.pDataSource = &m_Decoder;
|
||||||
|
|
||||||
|
result = ma_sound_init_ex(&engine, &soundConfig, &m_Sound);
|
||||||
|
if (!MD_ASSERT(result == MA_SUCCESS))
|
||||||
|
{
|
||||||
|
TraceError("Failed to initialize sound.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Identity = identity;
|
||||||
|
m_Initialized = true;
|
||||||
|
}
|
||||||
|
return m_Initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basically c&p
|
||||||
|
bool MaSoundInstance::InitFromFile(ma_engine& engine, const std::string& filePathOnDisk)
|
||||||
|
{
|
||||||
|
if (!m_Initialized)
|
||||||
|
{
|
||||||
|
ma_decoder_config decoderConfig = ma_decoder_config_init_default();
|
||||||
|
ma_result result = ma_decoder_init_file(filePathOnDisk.c_str(), &decoderConfig, &m_Decoder);
|
||||||
|
if (!MD_ASSERT(result == MA_SUCCESS))
|
||||||
|
{
|
||||||
|
TraceError("Failed to initialize sound file decoder.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ma_sound_config soundConfig = ma_sound_config_init();
|
||||||
|
soundConfig.pDataSource = &m_Decoder;
|
||||||
|
|
||||||
|
result = ma_sound_init_ex(&engine, &soundConfig, &m_Sound);
|
||||||
|
if (!MD_ASSERT(result == MA_SUCCESS))
|
||||||
|
{
|
||||||
|
TraceError("Failed to initialize sound.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Identity = filePathOnDisk;
|
||||||
|
m_Initialized = true;
|
||||||
|
}
|
||||||
|
return m_Initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaSoundInstance::Destroy()
|
||||||
|
{
|
||||||
|
if (m_Initialized)
|
||||||
|
{
|
||||||
|
ma_sound_uninit(&m_Sound);
|
||||||
|
ma_decoder_uninit(&m_Decoder);
|
||||||
|
}
|
||||||
|
m_Initialized = false;
|
||||||
|
m_Identity = "";
|
||||||
|
m_FadeTargetVolume = 0;
|
||||||
|
m_FadeRatePerFrame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaSoundInstance::IsInitialized() const
|
||||||
|
{
|
||||||
|
return m_Initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaSoundInstance::IsPlaying() const
|
||||||
|
{
|
||||||
|
return ma_sound_is_playing(&m_Sound) == MA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaSoundInstance::Play()
|
||||||
|
{
|
||||||
|
return m_Initialized && ma_sound_seek_to_pcm_frame(&m_Sound, 0) == MA_SUCCESS && ma_sound_start(&m_Sound) == MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaSoundInstance::Resume()
|
||||||
|
{
|
||||||
|
return m_Initialized && ma_sound_start(&m_Sound) == MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaSoundInstance::Stop()
|
||||||
|
{
|
||||||
|
return m_Initialized && ma_sound_stop(&m_Sound) == MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaSoundInstance::Loop()
|
||||||
|
{
|
||||||
|
ma_sound_set_looping(&m_Sound, MA_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
float MaSoundInstance::GetVolume() const
|
||||||
|
{
|
||||||
|
return ma_sound_get_volume(&m_Sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaSoundInstance::SetVolume(float volume)
|
||||||
|
{
|
||||||
|
ma_sound_set_volume(&m_Sound, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaSoundInstance::SetPitch(float pitch)
|
||||||
|
{
|
||||||
|
ma_sound_set_pitch(&m_Sound, pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaSoundInstance::SetPosition(float x, float y, float z)
|
||||||
|
{
|
||||||
|
ma_sound_set_position(&m_Sound, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& MaSoundInstance::GetIdentity() const
|
||||||
|
{
|
||||||
|
return m_Identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaSoundInstance::Config3D(bool toggle, float minDist, float maxDist, float rolloff)
|
||||||
|
{
|
||||||
|
ma_sound_set_spatialization_enabled(&m_Sound, toggle);
|
||||||
|
ma_sound_set_rolloff(&m_Sound, 1.0f);
|
||||||
|
ma_sound_set_min_distance(&m_Sound, minDist);
|
||||||
|
ma_sound_set_max_distance(&m_Sound, maxDist);
|
||||||
|
ma_sound_set_attenuation_model(&m_Sound, ma_attenuation_model_linear);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaSoundInstance::Fade(float toVolume, float secDurationFromMinMax)
|
||||||
|
{
|
||||||
|
toVolume = std::clamp<float>(toVolume, 0.0f, 1.0f);
|
||||||
|
m_FadeTargetVolume = toVolume;
|
||||||
|
|
||||||
|
float rate = 1.0f / 61.0f / secDurationFromMinMax;
|
||||||
|
m_FadeRatePerFrame = GetVolume() > toVolume ? -rate : rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaSoundInstance::StopFading()
|
||||||
|
{
|
||||||
|
m_FadeRatePerFrame = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MaSoundInstance::IsFading() const
|
||||||
|
{
|
||||||
|
return m_FadeRatePerFrame != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MaSoundInstance::Update(float volumeFactor) // volume factor is the user's volume
|
||||||
|
{
|
||||||
|
if (m_FadeRatePerFrame != 0)
|
||||||
|
{
|
||||||
|
float targetVolume = std::clamp<float>(m_FadeTargetVolume * volumeFactor, 0.0f, 1.0f);
|
||||||
|
float volume = std::clamp<float>(GetVolume() + (m_FadeRatePerFrame * volumeFactor), 0.0f, 1.0f);
|
||||||
|
if ((m_FadeRatePerFrame > 0 && volume >= targetVolume) || (m_FadeRatePerFrame < 0 && volume <= targetVolume))
|
||||||
|
{
|
||||||
|
volume = m_FadeTargetVolume * volumeFactor;
|
||||||
|
m_FadeRatePerFrame = 0.0f;
|
||||||
|
if (volume <= 0.0f)
|
||||||
|
ma_sound_stop(&m_Sound);
|
||||||
|
}
|
||||||
|
ma_sound_set_volume(&m_Sound, volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
54
src/AudioLib/MaSoundInstance.h
Normal file
54
src/AudioLib/MaSoundInstance.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <miniaudio.h>
|
||||||
|
|
||||||
|
inline constexpr float CS_CLIENT_FPS = 61.0f;
|
||||||
|
|
||||||
|
class MaSoundInstance
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool InitFromBuffer(ma_engine& engine, const std::vector<uint8_t>& buffer, const std::string& identity);
|
||||||
|
|
||||||
|
bool InitFromFile(ma_engine& engine, const std::string& filePathOnDisk);
|
||||||
|
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
bool IsInitialized() const;
|
||||||
|
|
||||||
|
bool IsPlaying() const;
|
||||||
|
|
||||||
|
bool Play();
|
||||||
|
|
||||||
|
bool Resume();
|
||||||
|
|
||||||
|
bool Stop();
|
||||||
|
|
||||||
|
void Loop();
|
||||||
|
|
||||||
|
float GetVolume() const;
|
||||||
|
|
||||||
|
void SetVolume(float volume);
|
||||||
|
|
||||||
|
void SetPitch(float pitch);
|
||||||
|
|
||||||
|
void SetPosition(float x, float y, float z);
|
||||||
|
|
||||||
|
const std::string& GetIdentity() const;
|
||||||
|
|
||||||
|
void Config3D(bool toggle, float minDist = 100.0f/*1m*/, float maxDist = 4000.0f/*40m*/, float rolloff = 1.0f);
|
||||||
|
|
||||||
|
void Fade(float toVolume, float secDurationFromMinMax);
|
||||||
|
|
||||||
|
void StopFading();
|
||||||
|
|
||||||
|
bool IsFading() const;
|
||||||
|
|
||||||
|
void Update(float volumeFactor = 1.0f);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_Identity;
|
||||||
|
ma_sound m_Sound{};
|
||||||
|
ma_decoder m_Decoder{};
|
||||||
|
bool m_Initialized{};
|
||||||
|
float m_FadeTargetVolume{};
|
||||||
|
float m_FadeRatePerFrame{};
|
||||||
|
};
|
||||||
268
src/AudioLib/SoundEngine.cpp
Normal file
268
src/AudioLib/SoundEngine.cpp
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "SoundEngine.h"
|
||||||
|
|
||||||
|
#include "EterBase/Random.h"
|
||||||
|
#include "EterBase/Timer.h"
|
||||||
|
#include "Eterpack/EterPackManager.h"
|
||||||
|
|
||||||
|
SoundEngine::SoundEngine()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SoundEngine::~SoundEngine()
|
||||||
|
{
|
||||||
|
for (auto& [name, instance] : m_Sounds2D)
|
||||||
|
instance.Destroy();
|
||||||
|
|
||||||
|
for (auto& instance : m_Sounds3D)
|
||||||
|
instance.Destroy();
|
||||||
|
|
||||||
|
ma_engine_uninit(&m_Engine);
|
||||||
|
m_Files.clear();
|
||||||
|
m_Sounds2D.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoundEngine::Initialize()
|
||||||
|
{
|
||||||
|
if (!MD_ASSERT(ma_engine_init(NULL, &m_Engine) == MA_SUCCESS))
|
||||||
|
{
|
||||||
|
TraceError("SoundEngine::Initialize: Failed to initialize engine.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetListenerPosition(0.0f, 0.0f, 0.0f);
|
||||||
|
SetListenerOrientation(0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::SetSoundVolume(float volume)
|
||||||
|
{
|
||||||
|
m_SoundVolume = std::clamp<float>(volume, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoundEngine::PlaySound2D(const std::string& name)
|
||||||
|
{
|
||||||
|
if (!Internal_LoadSoundFromPack(name))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto& instance = m_Sounds2D[name]; // 2d sounds are persistent, no need to destroy
|
||||||
|
instance.InitFromBuffer(m_Engine, m_Files[name], name);
|
||||||
|
instance.Config3D(false);
|
||||||
|
instance.SetVolume(m_SoundVolume);
|
||||||
|
return instance.Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
MaSoundInstance* SoundEngine::PlaySound3D(const std::string& name, float fx, float fy, float fz)
|
||||||
|
{
|
||||||
|
if (auto instance = Internal_GetInstance3D(name))
|
||||||
|
{
|
||||||
|
constexpr float minDist = 100.0f; // 1m
|
||||||
|
constexpr float maxDist = 4000.0f; // 40m
|
||||||
|
|
||||||
|
instance->SetPosition(fx, fy, fz);
|
||||||
|
instance->Config3D(true, minDist, maxDist, 1.0f);
|
||||||
|
instance->SetVolume(m_SoundVolume);
|
||||||
|
instance->Play();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaSoundInstance* SoundEngine::PlayAmbienceSound3D(float fx, float fy, float fz, const std::string& name, int loopCount)
|
||||||
|
{
|
||||||
|
auto vec3 = ma_engine_listener_get_position(&m_Engine, 0);
|
||||||
|
float dx = fx - vec3.x;
|
||||||
|
float dy = fy - vec3.y;
|
||||||
|
float dz = fz - vec3.z;
|
||||||
|
float distance = sqrtf(dx * dx + dy * dy + dz * dz);
|
||||||
|
return PlaySound3D(name, fx, fy, fz);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::StopAllSound3D()
|
||||||
|
{
|
||||||
|
for (auto& instance : m_Sounds3D)
|
||||||
|
instance.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::UpdateSoundInstance(float fx, float fy, float fz, uint32_t dwcurFrame, const NSound::TSoundInstanceVector* c_pSoundInstanceVector, bool checkFrequency, bool isMain)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < c_pSoundInstanceVector->size(); ++i)
|
||||||
|
{
|
||||||
|
const NSound::TSoundInstance& c_rSoundInstance = c_pSoundInstanceVector->at(i);
|
||||||
|
if (c_rSoundInstance.dwFrame == dwcurFrame)
|
||||||
|
{
|
||||||
|
if (checkFrequency)
|
||||||
|
{
|
||||||
|
float& lastPlay = m_PlaySoundHistoryMap[c_rSoundInstance.strSoundFileName];
|
||||||
|
float diff = CTimer::Instance().GetCurrentSecond() - lastPlay;
|
||||||
|
|
||||||
|
if (CTimer::Instance().GetCurrentSecond() - lastPlay < 0.3f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lastPlay = CTimer::Instance().GetCurrentSecond();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMain) // Sounds coming from main instance will always be played in 2d
|
||||||
|
{
|
||||||
|
// float volume = 0.9f + frandom(-0.1f, 0.1f);
|
||||||
|
// instance->SetPitch(pitch); // Should we play around with pitch a bit?
|
||||||
|
PlaySound2D(c_rSoundInstance.strSoundFileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// float volume = 0.9f + frandom(-0.1f, 0.1f);
|
||||||
|
// instance->SetPitch(pitch); // Should we play around with pitch a bit?
|
||||||
|
PlaySound3D(c_rSoundInstance.strSoundFileName, fx, fy, fz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoundEngine::FadeInMusic(const std::string& path, float targetVolume /* 1.0f by default */, float fadeInDurationSecondsFromMin)
|
||||||
|
{
|
||||||
|
if (path.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto& fadeOutMusic = m_Music[m_CurrentMusicIndex];
|
||||||
|
if (fadeOutMusic.IsPlaying() && path == fadeOutMusic.GetIdentity())
|
||||||
|
{
|
||||||
|
fadeOutMusic.Fade(targetVolume, fadeInDurationSecondsFromMin);
|
||||||
|
return fadeOutMusic.Resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're basically just swapping
|
||||||
|
FadeOutMusic(fadeOutMusic.GetIdentity());
|
||||||
|
m_CurrentMusicIndex = int(!m_CurrentMusicIndex);
|
||||||
|
|
||||||
|
auto& music = m_Music[m_CurrentMusicIndex];
|
||||||
|
music.Destroy();
|
||||||
|
music.InitFromFile(m_Engine, path);
|
||||||
|
music.Config3D(false);
|
||||||
|
music.Loop();
|
||||||
|
music.SetVolume(0.0f);
|
||||||
|
music.Fade(targetVolume, fadeInDurationSecondsFromMin);
|
||||||
|
return music.Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::FadeOutMusic(const std::string& name, float targetVolume, float fadeOutDurationSecondsFromMax)
|
||||||
|
{
|
||||||
|
for (auto& music : m_Music)
|
||||||
|
{
|
||||||
|
if (music.GetIdentity() == name)
|
||||||
|
music.Fade(targetVolume, fadeOutDurationSecondsFromMax);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::FadeOutAllMusic()
|
||||||
|
{
|
||||||
|
for (auto& music : m_Music)
|
||||||
|
FadeOutMusic(music.GetIdentity());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::SetMusicVolume(float volume)
|
||||||
|
{
|
||||||
|
m_MusicVolume = std::clamp<float>(volume, 0.0f, 1.0f);
|
||||||
|
for (auto& music : m_Music)
|
||||||
|
{
|
||||||
|
if (music.IsInitialized() && !music.IsFading()) // fading music will update itself
|
||||||
|
music.SetVolume(m_MusicVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::SaveVolume(bool isMinimized)
|
||||||
|
{
|
||||||
|
constexpr float ratePerSecond = 1.0f / CS_CLIENT_FPS;
|
||||||
|
// 1.0 to 0 in 1s if minimized, 3s if just out of focus
|
||||||
|
const float durationOnFullVolume = isMinimized ? 1.0 : 3.0f;
|
||||||
|
|
||||||
|
float outOfFocusVolume = 0.35f;
|
||||||
|
if (m_MasterVolume <= outOfFocusVolume)
|
||||||
|
outOfFocusVolume = m_MasterVolume;
|
||||||
|
|
||||||
|
m_MasterVolumeFadeTarget = isMinimized ? 0 : outOfFocusVolume;
|
||||||
|
m_MasterVolumeFadeRatePerFrame = -ratePerSecond / durationOnFullVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::RestoreVolume()
|
||||||
|
{
|
||||||
|
constexpr float ratePerSecond = 1.0f / CS_CLIENT_FPS;
|
||||||
|
constexpr float durationToFullVolume = 4.0f; // 0 to 1.0 in 4s
|
||||||
|
m_MasterVolumeFadeTarget = m_MasterVolume;
|
||||||
|
m_MasterVolumeFadeRatePerFrame = ratePerSecond / durationToFullVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::SetMasterVolume(float volume)
|
||||||
|
{
|
||||||
|
m_MasterVolume = volume;
|
||||||
|
ma_engine_set_volume(&m_Engine, volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::SetListenerPosition(float x, float y, float z)
|
||||||
|
{
|
||||||
|
ma_engine_listener_set_position(&m_Engine, 0, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::SetListenerOrientation(float forwardX, float forwardY, float forwardZ,
|
||||||
|
float upX, float upY, float upZ)
|
||||||
|
{
|
||||||
|
ma_engine_listener_set_direction(&m_Engine, 0, forwardX, forwardY, forwardZ);
|
||||||
|
ma_engine_listener_set_world_up(&m_Engine, 0, upX, upY, upZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::SetListenerVelocity(float x, float y, float z)
|
||||||
|
{
|
||||||
|
ma_engine_listener_set_velocity(&m_Engine, 0, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEngine::Update()
|
||||||
|
{
|
||||||
|
for (auto& music : m_Music)
|
||||||
|
music.Update(m_MusicVolume);
|
||||||
|
|
||||||
|
if (m_MasterVolumeFadeRatePerFrame)
|
||||||
|
{
|
||||||
|
float volume = ma_engine_get_volume(&m_Engine) + m_MasterVolumeFadeRatePerFrame;
|
||||||
|
if ((m_MasterVolumeFadeRatePerFrame > 0 && volume >= m_MasterVolumeFadeTarget) || (m_MasterVolumeFadeRatePerFrame < 0 && volume <= m_MasterVolumeFadeTarget))
|
||||||
|
{
|
||||||
|
volume = m_MasterVolumeFadeTarget;
|
||||||
|
m_MasterVolumeFadeRatePerFrame = 0.0f;
|
||||||
|
}
|
||||||
|
ma_engine_set_volume(&m_Engine, volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaSoundInstance* SoundEngine::Internal_GetInstance3D(const std::string& name)
|
||||||
|
{
|
||||||
|
if (Internal_LoadSoundFromPack(name))
|
||||||
|
{
|
||||||
|
for (auto& instance : m_Sounds3D)
|
||||||
|
{
|
||||||
|
if (!instance.IsPlaying())
|
||||||
|
{
|
||||||
|
instance.Destroy();
|
||||||
|
instance.InitFromBuffer(m_Engine, m_Files[name], name);
|
||||||
|
return &instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoundEngine::Internal_LoadSoundFromPack(const std::string& name)
|
||||||
|
{
|
||||||
|
if (m_Files.find(name) == m_Files.end())
|
||||||
|
{
|
||||||
|
LPCVOID soundData;
|
||||||
|
CMappedFile soundFile;
|
||||||
|
if (!CEterPackManager::Instance().Get(soundFile, name.c_str(), &soundData))
|
||||||
|
{
|
||||||
|
TraceError("Internal_LoadSoundFromPack: SoundEngine: Failed to register file '%s' - not found.", name.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& buffer = m_Files[name];
|
||||||
|
buffer.resize(soundFile.Size());
|
||||||
|
memcpy(buffer.data(), soundData, soundFile.Size());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
96
src/AudioLib/SoundEngine.h
Normal file
96
src/AudioLib/SoundEngine.h
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "../eterBase/Singleton.h"
|
||||||
|
#include "Type.h"
|
||||||
|
#include "MaSoundInstance.h"
|
||||||
|
|
||||||
|
//#include <miniaudio.h>
|
||||||
|
#include <array>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
struct SoundFile
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::vector<std::byte> buffer; // raw file data.
|
||||||
|
};
|
||||||
|
|
||||||
|
class SoundEngine : public CSingleton<SoundEngine>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum ESoundConfig
|
||||||
|
{
|
||||||
|
SOUND_INSTANCE_3D_MAX_NUM = 32,
|
||||||
|
};
|
||||||
|
// enum ESoundType
|
||||||
|
// {
|
||||||
|
// SOUND_TYPE_INTERFACE, // Interface sounds. Loaded on game opening, unloaded when the game ends.
|
||||||
|
// SOUND_TYPE_CHARACTER, // Character sounds(hit, damage, etc). Loaded on login, unloaded when the game ends.
|
||||||
|
// SOUND_TYPE_MONSTER, // monster attacks, hits, etc. Loaded and unloaded on warp
|
||||||
|
// SOUND_TYPE_AMBIENCE, // Wind, rain, birds, etc. Loaded and unloaded on warp
|
||||||
|
// SOUND_TYPE_MUSIC, // Bg music played on demand
|
||||||
|
// SOUND_TYPE_MAX_NUM,
|
||||||
|
// };
|
||||||
|
public:
|
||||||
|
SoundEngine();
|
||||||
|
|
||||||
|
~SoundEngine();
|
||||||
|
|
||||||
|
bool Initialize();
|
||||||
|
|
||||||
|
void SetSoundVolume(float volume);
|
||||||
|
|
||||||
|
bool PlaySound2D(const std::string& name);
|
||||||
|
|
||||||
|
MaSoundInstance* PlaySound3D(const std::string& name, float fx, float fy, float fz);
|
||||||
|
|
||||||
|
MaSoundInstance* PlayAmbienceSound3D(float fx, float fy, float fz, const std::string& name, int loopCount = 1);
|
||||||
|
|
||||||
|
void StopAllSound3D();
|
||||||
|
|
||||||
|
void UpdateSoundInstance(float fx, float fy, float fz, uint32_t dwcurFrame, const NSound::TSoundInstanceVector* c_pSoundInstanceVector, bool checkFrequency = false, bool isMain = false);
|
||||||
|
|
||||||
|
bool FadeInMusic(const std::string& path, float targetVolume = 1.0f, float fadeInDurationSecondsFromMin = 1.5f);
|
||||||
|
|
||||||
|
void FadeOutMusic(const std::string& name, float targetVolume = 0.0f, float fadeOutDurationSecondsFromMax = 1.5f);
|
||||||
|
|
||||||
|
void FadeOutAllMusic();
|
||||||
|
|
||||||
|
void SetMusicVolume(float volume);
|
||||||
|
|
||||||
|
void SaveVolume(bool isMinimized);
|
||||||
|
|
||||||
|
void RestoreVolume();
|
||||||
|
|
||||||
|
void SetMasterVolume(float volume);
|
||||||
|
|
||||||
|
void SetListenerPosition(float x, float y, float z);
|
||||||
|
|
||||||
|
void SetListenerOrientation(float forwardX, float forwardY, float forwardZ,
|
||||||
|
float upX, float upY, float upZ);
|
||||||
|
|
||||||
|
void SetListenerVelocity(float x, float y, float z);
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
MaSoundInstance* Internal_GetInstance3D(const std::string& name);
|
||||||
|
|
||||||
|
bool Internal_LoadSoundFromPack(const std::string& name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ma_engine m_Engine{};
|
||||||
|
std::unordered_map<std::string, std::vector<uint8_t>> m_Files;
|
||||||
|
std::unordered_map<std::string, MaSoundInstance> m_Sounds2D;
|
||||||
|
std::array<MaSoundInstance, SOUND_INSTANCE_3D_MAX_NUM> m_Sounds3D;
|
||||||
|
std::unordered_map<std::string, float> m_PlaySoundHistoryMap;
|
||||||
|
|
||||||
|
// One song at a time, but holding both current and previous for graceful fading
|
||||||
|
std::array<MaSoundInstance, 2> m_Music;
|
||||||
|
int m_CurrentMusicIndex{};
|
||||||
|
float m_MusicVolume{ 1.0 };
|
||||||
|
float m_SoundVolume{ 1.0 };
|
||||||
|
|
||||||
|
float m_MasterVolume{ 1.0 };
|
||||||
|
float m_MasterVolumeFadeTarget{};
|
||||||
|
float m_MasterVolumeFadeRatePerFrame{};
|
||||||
|
};
|
||||||
9
src/AudioLib/Stdafx.h
Normal file
9
src/AudioLib/Stdafx.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
//#include <windows.h>
|
||||||
|
|
||||||
|
#include "../eterBase/CRC32.h"
|
||||||
|
#include "../eterBase/Utils.h"
|
||||||
|
#include "../eterBase/Debug.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
138
src/AudioLib/Type.cpp
Normal file
138
src/AudioLib/Type.cpp
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
#include "StdAfx.h"
|
||||||
|
#include "Type.h"
|
||||||
|
#include "../EterLib/TextFileLoader.h"
|
||||||
|
|
||||||
|
std::string NSound::strResult;
|
||||||
|
|
||||||
|
const char* NSound::GetResultString()
|
||||||
|
{
|
||||||
|
return strResult.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NSound::SetResultString(const char* c_pszStr)
|
||||||
|
{
|
||||||
|
strResult.assign(c_pszStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NSound::LoadSoundInformationPiece(const char* c_szFileName, NSound::TSoundDataVector& rSoundDataVector, const char* c_szPathHeader)
|
||||||
|
{
|
||||||
|
std::string strResult;
|
||||||
|
strResult = c_szFileName;
|
||||||
|
|
||||||
|
CTextFileLoader* pkTextFileLoader = CTextFileLoader::Cache(c_szFileName);
|
||||||
|
if (!pkTextFileLoader)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CTextFileLoader& rkTextFileLoader = *pkTextFileLoader;
|
||||||
|
if (rkTextFileLoader.IsEmpty())
|
||||||
|
{
|
||||||
|
SetResultString((strResult + " Can not open file for reading").c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rkTextFileLoader.SetTop();
|
||||||
|
|
||||||
|
int iCount;
|
||||||
|
if (!rkTextFileLoader.GetTokenInteger("sounddatacount", &iCount))
|
||||||
|
{
|
||||||
|
SetResultString((strResult + " File format error, SoundDataCount Unable to find.").c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rSoundDataVector.clear();
|
||||||
|
rSoundDataVector.resize(iCount);
|
||||||
|
|
||||||
|
char szSoundDataHeader[32 + 1];
|
||||||
|
for (uint32_t i = 0; i < rSoundDataVector.size(); ++i)
|
||||||
|
{
|
||||||
|
_snprintf_s(szSoundDataHeader, sizeof(szSoundDataHeader), "sounddata%02d", i);
|
||||||
|
CTokenVector* pTokenVector;
|
||||||
|
if (!rkTextFileLoader.GetTokenVector(szSoundDataHeader, &pTokenVector))
|
||||||
|
{
|
||||||
|
SetResultString((strResult + " File format error: " + szSoundDataHeader + " Unable to find").c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (2 != pTokenVector->size())
|
||||||
|
{
|
||||||
|
SetResultString((strResult + " File format error: The size of the vector is not 2").c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rSoundDataVector[i].fTime = (float)atof(pTokenVector->at(0).c_str());
|
||||||
|
if (c_szPathHeader)
|
||||||
|
{
|
||||||
|
rSoundDataVector[i].strSoundFileName = c_szPathHeader;
|
||||||
|
rSoundDataVector[i].strSoundFileName += pTokenVector->at(1).c_str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rSoundDataVector[i].strSoundFileName = pTokenVector->at(1).c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TraceError("LoadSoundInformation %s -- %f -- %s", c_szFileName, rSoundDataVector[i].fTime, rSoundDataVector[i].strSoundFileName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
SetResultString((strResult + " Loaded").c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NSound::SaveSoundInformationPiece(const char* c_szFileName, NSound::TSoundDataVector& rSoundDataVector)
|
||||||
|
{
|
||||||
|
if (rSoundDataVector.empty()) // If no data is considered success
|
||||||
|
{
|
||||||
|
if (IsFile(c_szFileName)) // If the data is empty but there is a file
|
||||||
|
{
|
||||||
|
_unlink(c_szFileName); // erase.
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string strResult;
|
||||||
|
strResult = c_szFileName;
|
||||||
|
|
||||||
|
FILE* File = fopen(c_szFileName, "wt");
|
||||||
|
|
||||||
|
if (!File)
|
||||||
|
{
|
||||||
|
char szErrorText[256 + 1];
|
||||||
|
_snprintf_s(szErrorText, sizeof(szErrorText), "Failed to save file (%s).\nPlease check if it is read-only or you have no space on the disk.\n", c_szFileName);
|
||||||
|
LogBox(szErrorText, "Error");
|
||||||
|
SetResultString((strResult + " Cannot open file for writing").c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(File, "ScriptType CharacterSoundInformation\n");
|
||||||
|
fprintf(File, "\n");
|
||||||
|
|
||||||
|
fprintf(File, "SoundDataCount %llu\n", rSoundDataVector.size());
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < rSoundDataVector.size(); ++i)
|
||||||
|
{
|
||||||
|
NSound::TSoundData& rSoundData = rSoundDataVector[i];
|
||||||
|
fprintf(File, "SoundData%02d %f \"%s\"\n", i, rSoundData.fTime, rSoundData.strSoundFileName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(File);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NSound::DataToInstance(const TSoundDataVector& c_rSoundDataVector, TSoundInstanceVector* pSoundInstanceVector)
|
||||||
|
{
|
||||||
|
if (c_rSoundDataVector.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint32_t dwFPS = 60;
|
||||||
|
const float c_fFrameTime = 1.0f / float(dwFPS);
|
||||||
|
|
||||||
|
pSoundInstanceVector->clear();
|
||||||
|
pSoundInstanceVector->resize(c_rSoundDataVector.size());
|
||||||
|
for (uint32_t i = 0; i < c_rSoundDataVector.size(); ++i)
|
||||||
|
{
|
||||||
|
const TSoundData& c_rSoundData = c_rSoundDataVector[i];
|
||||||
|
TSoundInstance& rSoundInstance = pSoundInstanceVector->at(i);
|
||||||
|
|
||||||
|
rSoundInstance.dwFrame = (uint32_t)(c_rSoundData.fTime / c_fFrameTime);
|
||||||
|
rSoundInstance.strSoundFileName = c_rSoundData.strSoundFileName;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/AudioLib/Type.h
Normal file
29
src/AudioLib/Type.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace NSound
|
||||||
|
{
|
||||||
|
extern std::string strResult;
|
||||||
|
|
||||||
|
typedef struct SSoundData
|
||||||
|
{
|
||||||
|
float fTime;
|
||||||
|
std::string strSoundFileName;
|
||||||
|
} TSoundData;
|
||||||
|
typedef struct SSoundInstance
|
||||||
|
{
|
||||||
|
uint32_t dwFrame;
|
||||||
|
std::string strSoundFileName;
|
||||||
|
} TSoundInstance;
|
||||||
|
typedef std::vector<TSoundData> TSoundDataVector;
|
||||||
|
typedef std::vector<TSoundInstance> TSoundInstanceVector;
|
||||||
|
|
||||||
|
bool LoadSoundInformationPiece(const char* c_szFileName, TSoundDataVector& rSoundDataVector, const char* c_szPathHeader = NULL);
|
||||||
|
bool SaveSoundInformationPiece(const char* c_szFileName, TSoundDataVector& rSoundDataVector);
|
||||||
|
void DataToInstance(const TSoundDataVector& c_rSoundDataVector, TSoundInstanceVector* pSoundInstanceVector);
|
||||||
|
|
||||||
|
const char* GetResultString();
|
||||||
|
void SetResultString(const char* c_pszStr);
|
||||||
|
};
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
add_subdirectory(AudioLib)
|
||||||
add_subdirectory(Discord)
|
add_subdirectory(Discord)
|
||||||
add_subdirectory(EffectLib)
|
add_subdirectory(EffectLib)
|
||||||
add_subdirectory(EterBase)
|
add_subdirectory(EterBase)
|
||||||
@@ -8,7 +9,6 @@ add_subdirectory(EterLocale)
|
|||||||
add_subdirectory(EterPack)
|
add_subdirectory(EterPack)
|
||||||
add_subdirectory(EterPythonLib)
|
add_subdirectory(EterPythonLib)
|
||||||
add_subdirectory(GameLib)
|
add_subdirectory(GameLib)
|
||||||
add_subdirectory(MilesLib)
|
|
||||||
add_subdirectory(PRTerrainLib)
|
add_subdirectory(PRTerrainLib)
|
||||||
add_subdirectory(ScriptLib)
|
add_subdirectory(ScriptLib)
|
||||||
add_subdirectory(SpeedTreeLib)
|
add_subdirectory(SpeedTreeLib)
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ bool CEffectData::LoadScript(const char * c_szFileName)
|
|||||||
|
|
||||||
bool CEffectData::LoadSoundScriptData(const char * c_szFileName)
|
bool CEffectData::LoadSoundScriptData(const char * c_szFileName)
|
||||||
{
|
{
|
||||||
TSoundDataVector SoundDataVector;
|
NSound::TSoundDataVector SoundDataVector;
|
||||||
|
|
||||||
if (LoadSoundInformationPiece(c_szFileName, SoundDataVector))
|
if (LoadSoundInformationPiece(c_szFileName, SoundDataVector))
|
||||||
{
|
{
|
||||||
@@ -164,7 +164,7 @@ CEffectMeshScript * CEffectData::GetMeshPointer(DWORD dwPosition)
|
|||||||
return m_MeshVector[dwPosition];
|
return m_MeshVector[dwPosition];
|
||||||
}
|
}
|
||||||
|
|
||||||
TSoundInstanceVector * CEffectData::GetSoundInstanceVector()
|
NSound::TSoundInstanceVector * CEffectData::GetSoundInstanceVector()
|
||||||
{
|
{
|
||||||
return &m_SoundInstanceVector;
|
return &m_SoundInstanceVector;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../milesLib/Type.h"
|
#include "../AudioLib/Type.h"
|
||||||
|
|
||||||
#include "ParticleSystemData.h"
|
#include "ParticleSystemData.h"
|
||||||
#include "EffectMesh.h"
|
#include "EffectMesh.h"
|
||||||
@@ -30,7 +30,7 @@ class CEffectData
|
|||||||
DWORD GetLightCount();
|
DWORD GetLightCount();
|
||||||
CLightData * GetLightPointer(DWORD dwPosition);
|
CLightData * GetLightPointer(DWORD dwPosition);
|
||||||
|
|
||||||
TSoundInstanceVector * GetSoundInstanceVector();
|
NSound::TSoundInstanceVector * GetSoundInstanceVector();
|
||||||
|
|
||||||
float GetBoundingSphereRadius();
|
float GetBoundingSphereRadius();
|
||||||
D3DXVECTOR3 GetBoundingSpherePosition();
|
D3DXVECTOR3 GetBoundingSpherePosition();
|
||||||
@@ -52,7 +52,7 @@ class CEffectData
|
|||||||
TParticleVector m_ParticleVector;
|
TParticleVector m_ParticleVector;
|
||||||
TMeshVector m_MeshVector;
|
TMeshVector m_MeshVector;
|
||||||
TLightVector m_LightVector;
|
TLightVector m_LightVector;
|
||||||
TSoundInstanceVector m_SoundInstanceVector;
|
NSound::TSoundInstanceVector m_SoundInstanceVector;
|
||||||
|
|
||||||
float m_fBoundingSphereRadius;
|
float m_fBoundingSphereRadius;
|
||||||
D3DXVECTOR3 m_v3BoundingSpherePosition;
|
D3DXVECTOR3 m_v3BoundingSpherePosition;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#include "../eterBase/Stl.h"
|
#include "../eterBase/Stl.h"
|
||||||
#include "../eterLib/StateManager.h"
|
#include "../eterLib/StateManager.h"
|
||||||
#include "../MilesLib/SoundManager.h"
|
#include "../AudioLib/SoundEngine.h"
|
||||||
|
|
||||||
CDynamicPool<CEffectInstance> CEffectInstance::ms_kPool;
|
CDynamicPool<CEffectInstance> CEffectInstance::ms_kPool;
|
||||||
int CEffectInstance::ms_iRenderingEffectCount = 0;
|
int CEffectInstance::ms_iRenderingEffectCount = 0;
|
||||||
@@ -50,12 +50,12 @@ void CEffectInstance::UpdateSound()
|
|||||||
{
|
{
|
||||||
if (m_pSoundInstanceVector)
|
if (m_pSoundInstanceVector)
|
||||||
{
|
{
|
||||||
UpdateSoundInstance(m_dwFrame,
|
SoundEngine::Instance().UpdateSoundInstance(m_matGlobal._41,
|
||||||
*m_pSoundInstanceVector,
|
m_matGlobal._42,
|
||||||
m_matGlobal._41,
|
m_matGlobal._43,
|
||||||
m_matGlobal._42,
|
m_dwFrame,
|
||||||
m_matGlobal._43,
|
m_pSoundInstanceVector,
|
||||||
false);
|
false, false);
|
||||||
// NOTE : 매트릭스에서 위치를 직접 얻어온다 - [levites]
|
// NOTE : 매트릭스에서 위치를 직접 얻어온다 - [levites]
|
||||||
}
|
}
|
||||||
++m_dwFrame;
|
++m_dwFrame;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "../eterlib/GrpObjectInstance.h"
|
#include "../eterlib/GrpObjectInstance.h"
|
||||||
#include "../eterlib/Pool.h"
|
#include "../eterlib/Pool.h"
|
||||||
#include "../mileslib/Type.h"
|
#include "../AudioLib/Type.h"
|
||||||
|
|
||||||
#include "EffectElementBaseInstance.h"
|
#include "EffectElementBaseInstance.h"
|
||||||
#include "EffectData.h"
|
#include "EffectData.h"
|
||||||
@@ -77,7 +77,7 @@ class CEffectInstance : public CGraphicObjectInstance
|
|||||||
std::vector<CEffectMeshInstance*> m_MeshInstanceVector;
|
std::vector<CEffectMeshInstance*> m_MeshInstanceVector;
|
||||||
std::vector<CLightInstance*> m_LightInstanceVector;
|
std::vector<CLightInstance*> m_LightInstanceVector;
|
||||||
|
|
||||||
TSoundInstanceVector * m_pSoundInstanceVector;
|
NSound::TSoundInstanceVector * m_pSoundInstanceVector;
|
||||||
|
|
||||||
float m_fBoundingSphereRadius;
|
float m_fBoundingSphereRadius;
|
||||||
D3DXVECTOR3 m_v3BoundingSpherePosition;
|
D3DXVECTOR3 m_v3BoundingSpherePosition;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include "../eterLib/StdAfx.h"
|
#include "../eterLib/StdAfx.h"
|
||||||
#include "../eterLib/TextFileLoader.h"
|
#include "../eterLib/TextFileLoader.h"
|
||||||
|
|
||||||
#include "../milesLib/StdAfx.h"
|
#include "../AudioLib/StdAfx.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include "FrameController.h"
|
#include "FrameController.h"
|
||||||
|
|||||||
@@ -38,3 +38,9 @@ extern HWND g_PopupHwnd;
|
|||||||
} \
|
} \
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_DEBUG)
|
||||||
|
#define MD_ASSERT(expr) ((expr) ? true : (TraceError("MD_ASSERT('%s') failed at (%s:%d)", #expr, __FILE__, __LINE__), throw "ffs", false))
|
||||||
|
#else
|
||||||
|
#define MD_ASSERT(expr) ((expr) ? true : (TraceError("MD_ASSERT('%s') failed at (%s:%d)", #expr, __FILE__, __LINE__), false))
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
#ifndef __INC_ETERPACKLIB_ETERPACK_H__
|
#ifndef __INC_ETERPACKLIB_ETERPACK_H__
|
||||||
#define __INC_ETERPACKLIB_ETERPACK_H__
|
#define __INC_ETERPACKLIB_ETERPACK_H__
|
||||||
|
|
||||||
|
#ifndef MAKEFOURCC
|
||||||
|
#include <mmsyscom.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "EterBase/MappedFile.h"
|
#include "EterBase/MappedFile.h"
|
||||||
|
|
||||||
|
|
||||||
//#define CHECKSUM_CHECK_MD5
|
//#define CHECKSUM_CHECK_MD5
|
||||||
|
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
|
|
||||||
|
|
||||||
namespace eterpack
|
namespace eterpack
|
||||||
{
|
{
|
||||||
const DWORD c_PackCC = MAKEFOURCC('E', 'P', 'K', 'D');
|
const DWORD c_PackCC = MAKEFOURCC('E', 'P', 'K', 'D');
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "../effectLib/EffectManager.h"
|
#include "../effectLib/EffectManager.h"
|
||||||
#include "../milesLib/SoundManager.h"
|
#include "../AudioLib/SoundEngine.h"
|
||||||
|
|
||||||
#include "ActorInstance.h"
|
#include "ActorInstance.h"
|
||||||
#include "RaceData.h"
|
#include "RaceData.h"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "../EffectLib/EffectManager.h"
|
#include "../EffectLib/EffectManager.h"
|
||||||
#include "../milesLib/SoundManager.h"
|
#include "../AudioLib/SoundEngine.h"
|
||||||
|
|
||||||
#include "ActorInstance.h"
|
#include "ActorInstance.h"
|
||||||
#include "FlyingObjectManager.h"
|
#include "FlyingObjectManager.h"
|
||||||
@@ -29,9 +29,9 @@ void CActorInstance::SoundEventProcess(BOOL bCheckFrequency)
|
|||||||
if (!m_pkCurRaceMotionData)
|
if (!m_pkCurRaceMotionData)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const TSoundInstanceVector* c_pkVct_kSndInst = m_pkCurRaceMotionData->GetSoundInstanceVectorPointer();
|
const NSound::TSoundInstanceVector* c_pkVct_kSndInst = m_pkCurRaceMotionData->GetSoundInstanceVectorPointer();
|
||||||
UpdateSoundInstance(m_kCurMotNode.dwcurFrame, *c_pkVct_kSndInst,
|
SoundEngine::Instance().UpdateSoundInstance(m_x, m_y, m_z, m_kCurMotNode.dwcurFrame, c_pkVct_kSndInst,
|
||||||
m_x, m_y, m_z, bCheckFrequency);
|
bCheckFrequency, m_isMain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CActorInstance::MotionEventProcess(DWORD dwcurFrame, int iIndex, const CRaceMotionData::TMotionEventData * c_pData)
|
void CActorInstance::MotionEventProcess(DWORD dwcurFrame, int iIndex, const CRaceMotionData::TMotionEventData * c_pData)
|
||||||
@@ -247,7 +247,7 @@ void CActorInstance::ProcessMotionEventSound(const CRaceMotionData::TMotionEvent
|
|||||||
const CRaceMotionData::TMotionSoundEventData * c_pSoundData = (const CRaceMotionData::TMotionSoundEventData *)c_pData;
|
const CRaceMotionData::TMotionSoundEventData * c_pSoundData = (const CRaceMotionData::TMotionSoundEventData *)c_pData;
|
||||||
|
|
||||||
Tracenf("PLAY SOUND: %s", c_pSoundData->strSoundFileName.c_str());
|
Tracenf("PLAY SOUND: %s", c_pSoundData->strSoundFileName.c_str());
|
||||||
CSoundManager::Instance().PlaySound3D(m_x, m_y, m_z, c_pSoundData->strSoundFileName.c_str());
|
SoundEngine::Instance().PlaySound3D(c_pSoundData->strSoundFileName.c_str(), m_x, m_y, m_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CActorInstance::ProcessMotionEventFly(const CRaceMotionData::TMotionEventData * c_pData)
|
void CActorInstance::ProcessMotionEventFly(const CRaceMotionData::TMotionEventData * c_pData)
|
||||||
|
|||||||
@@ -1316,27 +1316,27 @@ void CArea::TAmbienceInstance::__Update(float fxCenter, float fyCenter, float fz
|
|||||||
void CArea::TAmbienceInstance::UpdateOnceSound(float fxCenter, float fyCenter, float fzCenter)
|
void CArea::TAmbienceInstance::UpdateOnceSound(float fxCenter, float fyCenter, float fzCenter)
|
||||||
{
|
{
|
||||||
float fDistance = sqrtf((fx - fxCenter)*(fx - fxCenter) + (fy - fyCenter)*(fy - fyCenter) + (fz - fzCenter)*(fz - fzCenter));
|
float fDistance = sqrtf((fx - fxCenter)*(fx - fxCenter) + (fy - fyCenter)*(fy - fyCenter) + (fz - fzCenter)*(fz - fzCenter));
|
||||||
if (DWORD(fDistance) < dwRange)
|
if (uint32_t(fDistance) < dwRange)
|
||||||
{
|
{
|
||||||
if (!pSample)
|
if (!playSoundInstance)
|
||||||
{
|
{
|
||||||
if (AmbienceData.AmbienceSoundVector.empty())
|
if (AmbienceData.AmbienceSoundVector.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const char * c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str();
|
const char* c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str();
|
||||||
pSample = CSoundManager::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName);
|
playSoundInstance = SoundEngine::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName);
|
||||||
// Tracef(" %d : OncePlay [%f] : %s\n", iPlaySoundIndex, fDistance, c_szFileName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (playSoundInstance)
|
||||||
{
|
{
|
||||||
pSample.reset();
|
playSoundInstance->Stop();
|
||||||
|
playSoundInstance = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CArea::TAmbienceInstance::UpdateStepSound(float fxCenter, float fyCenter, float fzCenter)
|
void CArea::TAmbienceInstance::UpdateStepSound(float fxCenter, float fyCenter, float fzCenter)
|
||||||
{
|
{
|
||||||
float fDistance = sqrtf((fx - fxCenter)*(fx - fxCenter) + (fy - fyCenter)*(fy - fyCenter) + (fz - fzCenter)*(fz - fzCenter));
|
float fDistance = sqrtf((fx - fxCenter) * (fx - fxCenter) + (fy - fyCenter) * (fy - fyCenter) + (fz - fzCenter) * (fz - fzCenter));
|
||||||
if (DWORD(fDistance) < dwRange)
|
if (DWORD(fDistance) < dwRange)
|
||||||
{
|
{
|
||||||
float fcurTime = CTimer::Instance().GetCurrentSecond();
|
float fcurTime = CTimer::Instance().GetCurrentSecond();
|
||||||
@@ -1346,9 +1346,8 @@ void CArea::TAmbienceInstance::UpdateStepSound(float fxCenter, float fyCenter, f
|
|||||||
if (AmbienceData.AmbienceSoundVector.empty())
|
if (AmbienceData.AmbienceSoundVector.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const char * c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str();
|
const char* c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str();
|
||||||
pSample = CSoundManager::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName);
|
playSoundInstance = SoundEngine::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName);
|
||||||
// Tracef(" %d : StepPlay [%f] : %s\n", iPlaySoundIndex, fDistance, c_szFileName);
|
|
||||||
|
|
||||||
fNextPlayTime = CTimer::Instance().GetCurrentSecond();
|
fNextPlayTime = CTimer::Instance().GetCurrentSecond();
|
||||||
fNextPlayTime += AmbienceData.fPlayInterval + frandom(0.0f, AmbienceData.fPlayIntervalVariation);
|
fNextPlayTime += AmbienceData.fPlayInterval + frandom(0.0f, AmbienceData.fPlayIntervalVariation);
|
||||||
@@ -1356,7 +1355,7 @@ void CArea::TAmbienceInstance::UpdateStepSound(float fxCenter, float fyCenter, f
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pSample.reset();
|
playSoundInstance = nullptr;
|
||||||
fNextPlayTime = 0.0f;
|
fNextPlayTime = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1364,20 +1363,24 @@ void CArea::TAmbienceInstance::UpdateStepSound(float fxCenter, float fyCenter, f
|
|||||||
void CArea::TAmbienceInstance::UpdateLoopSound(float fxCenter, float fyCenter, float fzCenter)
|
void CArea::TAmbienceInstance::UpdateLoopSound(float fxCenter, float fyCenter, float fzCenter)
|
||||||
{
|
{
|
||||||
float fDistance = sqrtf((fx - fxCenter) * (fx - fxCenter) + (fy - fyCenter) * (fy - fyCenter) + (fz - fzCenter) * (fz - fzCenter));
|
float fDistance = sqrtf((fx - fxCenter) * (fx - fxCenter) + (fy - fyCenter) * (fy - fyCenter) + (fz - fzCenter) * (fz - fzCenter));
|
||||||
if (DWORD(fDistance) < dwRange)
|
if (uint32_t(fDistance) < dwRange)
|
||||||
{
|
{
|
||||||
if (!pSample)
|
if (!playSoundInstance)
|
||||||
{
|
{
|
||||||
pSample = CSoundManager::Instance().PlayAmbienceSound3D(fx, fy, fz, AmbienceData.AmbienceSoundVector[0], 0);
|
if (AmbienceData.AmbienceSoundVector.empty())
|
||||||
}
|
return;
|
||||||
else
|
|
||||||
{
|
const char* c_szFileName = AmbienceData.AmbienceSoundVector[0].c_str();
|
||||||
pSample->SetVolume(__GetVolumeFromDistance(fDistance));
|
playSoundInstance = SoundEngine::Instance().PlayAmbienceSound3D(fx, fy, fz, c_szFileName, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (playSoundInstance)
|
||||||
|
playSoundInstance->SetVolume(__GetVolumeFromDistance(fDistance));
|
||||||
}
|
}
|
||||||
else
|
else if (playSoundInstance)
|
||||||
{
|
{
|
||||||
pSample.reset();
|
playSoundInstance->Stop();
|
||||||
|
playSoundInstance = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class CArea
|
|||||||
float fx, fy, fz;
|
float fx, fy, fz;
|
||||||
DWORD dwRange;
|
DWORD dwRange;
|
||||||
float fMaxVolumeAreaPercentage;
|
float fMaxVolumeAreaPercentage;
|
||||||
std::unique_ptr<SoundSample> pSample;
|
MaSoundInstance* playSoundInstance;
|
||||||
float fNextPlayTime;
|
float fNextPlayTime;
|
||||||
prt::TPropertyAmbience AmbienceData;
|
prt::TPropertyAmbience AmbienceData;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
class CProperty;
|
class CProperty;
|
||||||
|
|
||||||
#include "../eterLib/SkyBox.h"
|
#include "../eterLib/SkyBox.h"
|
||||||
#include "../mileslib/SoundManager.h"
|
#include "../AudioLib/SoundEngine.h"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
// Property
|
// Property
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ float CRaceMotionData::GetEventStartTime(DWORD dwIndex) const
|
|||||||
return m_MotionEventDataVector[dwIndex]->fStartingTime;
|
return m_MotionEventDataVector[dwIndex]->fStartingTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TSoundInstanceVector * CRaceMotionData::GetSoundInstanceVectorPointer() const
|
const NSound::TSoundInstanceVector * CRaceMotionData::GetSoundInstanceVectorPointer() const
|
||||||
{
|
{
|
||||||
return &m_SoundInstanceVector;
|
return &m_SoundInstanceVector;
|
||||||
}
|
}
|
||||||
@@ -553,7 +553,7 @@ bool CRaceMotionData::SaveMotionData(const char * c_szFileName)
|
|||||||
#endif
|
#endif
|
||||||
bool CRaceMotionData::LoadSoundScriptData(const char * c_szFileName)
|
bool CRaceMotionData::LoadSoundScriptData(const char * c_szFileName)
|
||||||
{
|
{
|
||||||
TSoundDataVector SoundDataVector;
|
NSound::TSoundDataVector SoundDataVector;
|
||||||
if (!LoadSoundInformationPiece(c_szFileName, SoundDataVector))
|
if (!LoadSoundInformationPiece(c_szFileName, SoundDataVector))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "MilesLib/Type.h"
|
#include "AudioLib/Type.h"
|
||||||
#include "RaceMotionDataEvent.h"
|
#include "RaceMotionDataEvent.h"
|
||||||
|
|
||||||
class CRaceMotionData
|
class CRaceMotionData
|
||||||
@@ -253,7 +253,7 @@ class CRaceMotionData
|
|||||||
float GetEventStartTime(DWORD dwIndex) const;
|
float GetEventStartTime(DWORD dwIndex) const;
|
||||||
|
|
||||||
// Sound Data
|
// Sound Data
|
||||||
const TSoundInstanceVector * GetSoundInstanceVectorPointer() const;
|
const NSound::TSoundInstanceVector * GetSoundInstanceVectorPointer() const;
|
||||||
|
|
||||||
// File
|
// File
|
||||||
#ifdef WORLD_EDITOR
|
#ifdef WORLD_EDITOR
|
||||||
@@ -291,7 +291,7 @@ class CRaceMotionData
|
|||||||
BOOL m_bCancelEnableSkill;
|
BOOL m_bCancelEnableSkill;
|
||||||
|
|
||||||
TMotionEventDataVector m_MotionEventDataVector;
|
TMotionEventDataVector m_MotionEventDataVector;
|
||||||
TSoundInstanceVector m_SoundInstanceVector;
|
NSound::TSoundInstanceVector m_SoundInstanceVector;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BOOL m_hasSplashEvent;
|
BOOL m_hasSplashEvent;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#include "../eterBase/Random.h"
|
#include "../eterBase/Random.h"
|
||||||
|
|
||||||
#include "../eterLib/StdAfx.h"
|
#include "../eterLib/StdAfx.h"
|
||||||
#include "../milesLib/StdAfx.h"
|
#include "../AudioLib/StdAfx.h"
|
||||||
#include "../effectLib/StdAfx.h"
|
#include "../effectLib/StdAfx.h"
|
||||||
|
|
||||||
#include "GameType.h"
|
#include "GameType.h"
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
file(GLOB_RECURSE FILE_SOURCES "*.h" "*.c" "*.cpp")
|
|
||||||
|
|
||||||
add_library(MilesLib STATIC ${FILE_SOURCES})
|
|
||||||
|
|
||||||
target_link_libraries(MilesLib
|
|
||||||
lzo2
|
|
||||||
)
|
|
||||||
|
|
||||||
GroupSourcesByFolder(MilesLib)
|
|
||||||
@@ -1,135 +0,0 @@
|
|||||||
#include "Stdafx.h"
|
|
||||||
#include "MSSFileAPI.hpp"
|
|
||||||
|
|
||||||
#include "EterBase/Timer.h"
|
|
||||||
#include "EterBase/Utils.h"
|
|
||||||
|
|
||||||
#include "EterPack/StdAfx.h"
|
|
||||||
#include "EterPack/EterPackManager.h"
|
|
||||||
|
|
||||||
#include <mss.h>
|
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <memory>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
enum ESeekType
|
|
||||||
{
|
|
||||||
SEEK_TYPE_BEGIN,
|
|
||||||
SEEK_TYPE_CURRENT,
|
|
||||||
SEEK_TYPE_END
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CSeekPackFile
|
|
||||||
{
|
|
||||||
std::vector<uint8_t> packFile;
|
|
||||||
|
|
||||||
U32 seek_position;
|
|
||||||
|
|
||||||
~CSeekPackFile()
|
|
||||||
{
|
|
||||||
seek_position = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
U32 Seek(S32 offset, U32 type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case SEEK_TYPE_BEGIN:
|
|
||||||
if (offset > packFile.size())
|
|
||||||
offset = packFile.size();
|
|
||||||
|
|
||||||
seek_position = offset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SEEK_TYPE_CURRENT:
|
|
||||||
seek_position = MIN(seek_position + offset, packFile.size());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SEEK_TYPE_END:
|
|
||||||
seek_position = MAX(0, packFile.size() - offset);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return seek_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL Read(void* dest, int bytes)
|
|
||||||
{
|
|
||||||
if (seek_position + bytes > packFile.size())
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
memcpy(dest, (const char*)packFile.data() + seek_position, bytes);
|
|
||||||
seek_position += bytes;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
static std::unordered_map<U32, CSeekPackFile> gs_SoundFile;
|
|
||||||
static std::vector<U32> gs_FreeIndexes;
|
|
||||||
static U32 gs_SoundFileIndex = 0;
|
|
||||||
static std::mutex gs_SoundFileMutex;
|
|
||||||
|
|
||||||
U32 AILCALLBACK open_callback(MSS_FILE const* filename, UINTa* file_handle)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(gs_SoundFileMutex);
|
|
||||||
|
|
||||||
U32 index = 0;
|
|
||||||
if (!gs_FreeIndexes.empty())
|
|
||||||
{
|
|
||||||
index = gs_FreeIndexes.back();
|
|
||||||
gs_FreeIndexes.pop_back();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
index = ++gs_SoundFileIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPCVOID pData;
|
|
||||||
CMappedFile mappedFile;
|
|
||||||
if (!CEterPackManager::instance().Get(mappedFile, filename, &pData))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
gs_SoundFile[index].packFile.resize(mappedFile.Size());
|
|
||||||
memcpy(gs_SoundFile[index].packFile.data(), pData, mappedFile.Size());
|
|
||||||
|
|
||||||
*file_handle = index;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AILCALLBACK close_callback(UINTa file_handle)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> l(gs_SoundFileMutex);
|
|
||||||
|
|
||||||
gs_SoundFile.erase(file_handle);
|
|
||||||
gs_FreeIndexes.push_back(file_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
S32 AILCALLBACK seek_callback(UINTa file_handle, S32 offset, U32 type)
|
|
||||||
{
|
|
||||||
auto it = gs_SoundFile.find(file_handle);
|
|
||||||
if (it == gs_SoundFile.end())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return it->second.Seek(offset, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
U32 AILCALLBACK read_callback(UINTa file_handle, void* buffer, U32 bytes)
|
|
||||||
{
|
|
||||||
auto it = gs_SoundFile.find(file_handle);
|
|
||||||
if (it == gs_SoundFile.end())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
DWORD dwRealSize = MIN(it->second.packFile.size(), bytes);
|
|
||||||
it->second.Read(buffer, dwRealSize);
|
|
||||||
return dwRealSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegisterMilesFileAPI()
|
|
||||||
{
|
|
||||||
AIL_set_file_callbacks(open_callback, close_callback,
|
|
||||||
seek_callback, read_callback);
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
void RegisterMilesFileAPI();
|
|
||||||
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
#include "Stdafx.h"
|
|
||||||
#include "MusicInstance.hpp"
|
|
||||||
|
|
||||||
MusicInstance::MusicInstance(HSTREAM stream, std::string_view filename,
|
|
||||||
float fVolume, float fVolumeSpeed)
|
|
||||||
: MusicState(MUSIC_STATE_FADE_IN)
|
|
||||||
, fVolume(fVolume)
|
|
||||||
, fLimitVolume(0.0f)
|
|
||||||
, fVolumeSpeed(fVolumeSpeed)
|
|
||||||
, filename(filename)
|
|
||||||
, stream(stream)
|
|
||||||
{
|
|
||||||
this->stream.SetVolume(fVolume);
|
|
||||||
this->stream.Play(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MusicInstance::Update(float musicVolume)
|
|
||||||
{
|
|
||||||
if (MUSIC_STATE_OFF == MusicState)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
switch (MusicState)
|
|
||||||
{
|
|
||||||
case MUSIC_STATE_FADE_IN:
|
|
||||||
fVolume += fVolumeSpeed;
|
|
||||||
|
|
||||||
if (fVolume >= musicVolume)
|
|
||||||
{
|
|
||||||
fVolume = musicVolume;
|
|
||||||
fVolumeSpeed = 0.0f;
|
|
||||||
MusicState = MUSIC_STATE_PLAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.SetVolume(fVolume);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MUSIC_STATE_FADE_LIMIT_OUT:
|
|
||||||
fVolume -= fVolumeSpeed;
|
|
||||||
|
|
||||||
if (fVolume <= fLimitVolume)
|
|
||||||
{
|
|
||||||
fVolume = fLimitVolume;
|
|
||||||
fVolumeSpeed = 0.0f;
|
|
||||||
MusicState = MUSIC_STATE_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.SetVolume(fVolume);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MUSIC_STATE_FADE_OUT:
|
|
||||||
fVolume -= fVolumeSpeed;
|
|
||||||
return fVolume > 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string_view>
|
|
||||||
#include "SoundStream.hpp"
|
|
||||||
#include <mss.h>
|
|
||||||
|
|
||||||
enum MusicState
|
|
||||||
{
|
|
||||||
MUSIC_STATE_OFF,
|
|
||||||
MUSIC_STATE_PLAY,
|
|
||||||
MUSIC_STATE_FADE_IN,
|
|
||||||
MUSIC_STATE_FADE_OUT,
|
|
||||||
MUSIC_STATE_FADE_LIMIT_OUT,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO(tim): make members private?
|
|
||||||
struct MusicInstance
|
|
||||||
{
|
|
||||||
MusicInstance(HSTREAM stream, std::string_view filename,
|
|
||||||
float fVolume, float fVolumeSpeed);
|
|
||||||
|
|
||||||
bool Update(float musicVolume);
|
|
||||||
|
|
||||||
MusicState MusicState;
|
|
||||||
float fVolume;
|
|
||||||
float fLimitVolume;
|
|
||||||
float fVolumeSpeed;
|
|
||||||
std::string filename;
|
|
||||||
SoundStream stream;
|
|
||||||
};
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#include "Stdafx.h"
|
|
||||||
#include "SampleFile.hpp"
|
|
||||||
|
|
||||||
SampleFile::SampleFile(std::string_view filename, std::vector<uint8_t>&& data)
|
|
||||||
: m_filename(filename), fileData(std::forward<std::vector<uint8_t>>(data))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const void *SampleFile::GetData() const
|
|
||||||
{
|
|
||||||
return fileData.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t SampleFile::GetSize() const
|
|
||||||
{
|
|
||||||
return fileData.size();
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include "EterBase/StdAfx.h"
|
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
#include "EterPack/StdAfx.h"
|
|
||||||
#include "EterPack/EterPackmanager.h"
|
|
||||||
|
|
||||||
class SampleFile
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SampleFile(std::string_view filename, std::vector<uint8_t>&& data);
|
|
||||||
|
|
||||||
const std::string &GetFilename() const
|
|
||||||
{
|
|
||||||
return m_filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
const void *GetData() const;
|
|
||||||
uint32_t GetSize() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_filename;
|
|
||||||
std::vector<uint8_t> fileData;
|
|
||||||
};
|
|
||||||
|
|
||||||
using SampleFilePtr = std::shared_ptr<SampleFile>;
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#include "Stdafx.h"
|
|
||||||
#include "SampleFileCache.hpp"
|
|
||||||
#include "EterBase/Debug.h"
|
|
||||||
#include "EterLib/ResourceManager.h"
|
|
||||||
|
|
||||||
#include "EterPack/StdAfx.h"
|
|
||||||
#include "EterPack/EterPackManager.h"
|
|
||||||
|
|
||||||
SampleFilePtr SampleFileCache::Get(std::string_view filename)
|
|
||||||
{
|
|
||||||
const auto it = m_samples.find(filename);
|
|
||||||
if (it != m_samples.end())
|
|
||||||
return it->second;
|
|
||||||
|
|
||||||
LPCVOID pData;
|
|
||||||
CMappedFile mappedFile;
|
|
||||||
|
|
||||||
if(!CEterPackManager::instance().Get(mappedFile, filename.data(), &pData))
|
|
||||||
{
|
|
||||||
TraceError("Failed to open %s", filename);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> fileData;
|
|
||||||
fileData.resize(mappedFile.Size());
|
|
||||||
memcpy(fileData.data(), pData, mappedFile.Size());
|
|
||||||
|
|
||||||
auto sample = std::make_shared<SampleFile>(filename, std::move(fileData));
|
|
||||||
m_samples.emplace(sample->GetFilename(), sample);
|
|
||||||
return sample;
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "SampleFile.hpp"
|
|
||||||
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
class SampleFileCache
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SampleFilePtr Get(std::string_view filename);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unordered_map<std::string_view, SampleFilePtr> m_samples;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -1,393 +0,0 @@
|
|||||||
#include "StdAfx.h"
|
|
||||||
#include "SoundManager.h"
|
|
||||||
|
|
||||||
#include "EterBase/Timer.h"
|
|
||||||
#include "EterBase/Utils.h"
|
|
||||||
#include "EterBase/Debug.h"
|
|
||||||
#undef min
|
|
||||||
#undef max
|
|
||||||
#include <cmath>
|
|
||||||
//#define IS_STATIC
|
|
||||||
//#include <StepTimer.h>
|
|
||||||
|
|
||||||
#include "MSSFileAPI.hpp"
|
|
||||||
#include <mss.h>
|
|
||||||
|
|
||||||
MilesLibrary::MilesLibrary()
|
|
||||||
{
|
|
||||||
Register_RIB(MP3Dec);
|
|
||||||
//AIL_configure_logging("miles.log", nullptr, 2);
|
|
||||||
|
|
||||||
AIL_startup();
|
|
||||||
|
|
||||||
RegisterMilesFileAPI();
|
|
||||||
}
|
|
||||||
|
|
||||||
MilesLibrary::~MilesLibrary()
|
|
||||||
{
|
|
||||||
AIL_shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
CSoundManager::CSoundManager()
|
|
||||||
: m_isSoundDisable(false), m_max2dSoundsPlaying(8), m_max3dSoundsPlaying(64), m_maxMusicPlaying(4),
|
|
||||||
m_fxPosition(0.0f), m_fyPosition(0.0f), m_fzPosition(0.0f), m_fSoundScale(200.0f), m_fAmbienceSoundScale(1000.0f),
|
|
||||||
m_fSoundVolume(1.0f), m_fMusicVolume(1.0f), m_fBackupMusicVolume(0.0f), m_fBackupSoundVolume(0.0f),
|
|
||||||
m_driver(nullptr)
|
|
||||||
{
|
|
||||||
// ctor
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CSoundManager::Create()
|
|
||||||
{
|
|
||||||
m_driver = AIL_open_digital_driver(44100, 16, MSS_MC_USE_SYSTEM_CONFIG , 0);
|
|
||||||
if (!m_driver)
|
|
||||||
{
|
|
||||||
Tracenf("AIL_open_digital_driver(): %s", AIL_last_error());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
AIL_set_3D_distance_factor(m_driver, 0.001f);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::SetPosition(float fx, float fy, float fz)
|
|
||||||
{
|
|
||||||
m_fxPosition = fx;
|
|
||||||
m_fyPosition = fy;
|
|
||||||
m_fzPosition = fz;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::SetDirection(float fxDir, float fyDir, float fzDir, float fxUp, float fyUp, float fzUp)
|
|
||||||
{
|
|
||||||
if (!m_driver)
|
|
||||||
return;
|
|
||||||
|
|
||||||
AIL_set_listener_3D_orientation(m_driver, fxDir, fyDir, -fzDir, fxUp, fyUp, -fzUp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::Update()
|
|
||||||
{
|
|
||||||
for (auto it = m_sounds2d.begin(); it != m_sounds2d.end();)
|
|
||||||
{
|
|
||||||
if (it->IsDone())
|
|
||||||
it = m_sounds2d.erase(it);
|
|
||||||
else
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto it = m_sounds3d.begin(); it != m_sounds3d.end();)
|
|
||||||
{
|
|
||||||
if (it->IsDone())
|
|
||||||
it = m_sounds3d.erase(it);
|
|
||||||
else
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto it = m_music.begin(); it != m_music.end();)
|
|
||||||
{
|
|
||||||
// If Update() returns false, the song has finished playing.
|
|
||||||
if (it->second.Update(m_fMusicVolume))
|
|
||||||
++it;
|
|
||||||
else
|
|
||||||
it = m_music.erase(it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float CSoundManager::GetSoundScale()
|
|
||||||
{
|
|
||||||
return m_fSoundScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::SetSoundScale(float fScale)
|
|
||||||
{
|
|
||||||
m_fSoundScale = fScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::SetAmbienceSoundScale(float fScale)
|
|
||||||
{
|
|
||||||
m_fAmbienceSoundScale = fScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::SetSoundVolume(float fVolume)
|
|
||||||
{
|
|
||||||
if (m_isSoundDisable)
|
|
||||||
{
|
|
||||||
m_fBackupSoundVolume = fVolume;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fVolume = std::max(std::min(fVolume, 1.0f), 0.0f);
|
|
||||||
m_fSoundVolume = fVolume;
|
|
||||||
m_fBackupSoundVolume = fVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::SetMusicVolume(float fVolume)
|
|
||||||
{
|
|
||||||
if (m_isSoundDisable)
|
|
||||||
{
|
|
||||||
m_fBackupMusicVolume = fVolume;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fVolume = std::max(std::min(fVolume, 1.0f), 0.0f);
|
|
||||||
m_fMusicVolume = fVolume;
|
|
||||||
m_fBackupMusicVolume = fVolume;
|
|
||||||
|
|
||||||
for (auto &p : m_music)
|
|
||||||
{
|
|
||||||
if (MUSIC_STATE_OFF == p.second.MusicState)
|
|
||||||
continue;
|
|
||||||
if (MUSIC_STATE_FADE_OUT == p.second.MusicState)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
p.second.fVolume = fVolume;
|
|
||||||
p.second.stream.SetVolume(fVolume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::SaveVolume()
|
|
||||||
{
|
|
||||||
// NOTE : 두번 이상 Save를 시도할때는 그냥 Return
|
|
||||||
if (m_isSoundDisable)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float fBackupMusicVolume = m_fMusicVolume;
|
|
||||||
float fBackupSoundVolume = m_fSoundVolume;
|
|
||||||
SetMusicVolume(0.0f);
|
|
||||||
SetSoundVolume(0.0f);
|
|
||||||
m_fBackupMusicVolume = fBackupMusicVolume;
|
|
||||||
m_fBackupSoundVolume = fBackupSoundVolume;
|
|
||||||
m_isSoundDisable = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::RestoreVolume()
|
|
||||||
{
|
|
||||||
m_isSoundDisable = false;
|
|
||||||
SetMusicVolume(m_fBackupMusicVolume);
|
|
||||||
SetSoundVolume(m_fBackupSoundVolume);
|
|
||||||
}
|
|
||||||
|
|
||||||
float CSoundManager::GetSoundVolume()
|
|
||||||
{
|
|
||||||
return m_fSoundVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
float CSoundManager::GetMusicVolume()
|
|
||||||
{
|
|
||||||
return m_fMusicVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::PlaySound2D(std::string_view filename)
|
|
||||||
{
|
|
||||||
if (0.0f == GetSoundVolume())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_sounds2d.size() >= m_max2dSoundsPlaying)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto file = m_cache.Get(filename);
|
|
||||||
if (!file)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_driver)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto sample = AIL_allocate_sample_handle(m_driver);
|
|
||||||
if (!sample)
|
|
||||||
{
|
|
||||||
Tracenf("AIL_allocate_sample_handle(): %s for %s", AIL_last_error(), filename.data());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sounds2d.emplace_back(sample);
|
|
||||||
m_sounds2d.back().SetFile(file);
|
|
||||||
m_sounds2d.back().SetVolume(GetSoundVolume());
|
|
||||||
m_sounds2d.back().Play(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
float CSoundManager::__GetVolumeFromDistance(float fDistance)
|
|
||||||
{
|
|
||||||
return GetSoundVolume() - (fDistance / 2500);
|
|
||||||
}
|
|
||||||
// return 1.0f / (1.0f + (1.0f * (fDistance - 1.0f)));
|
|
||||||
|
|
||||||
|
|
||||||
void CSoundManager::PlaySound3D(float fx, float fy, float fz, std::string_view filename, int iPlayCount)
|
|
||||||
{
|
|
||||||
if (0.0f == GetSoundVolume())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_sounds3d.size() >= m_max3dSoundsPlaying)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto file = m_cache.Get(filename);
|
|
||||||
if (!file)
|
|
||||||
{
|
|
||||||
Tracenf("Not playing %s file not found", filename.data());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto sample = AIL_allocate_sample_handle(m_driver);
|
|
||||||
if (!sample)
|
|
||||||
{
|
|
||||||
Tracenf("AIL_allocate_sample_handle(): %s for %s", AIL_last_error(), filename.data());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float fDistance = sqrtf((fx - m_fxPosition) * (fx - m_fxPosition) + (fy - m_fyPosition) * (fy - m_fyPosition) +
|
|
||||||
(fz - m_fzPosition) * (fz - m_fzPosition));
|
|
||||||
Tracenf("SampSet distance {} {}", fDistance ,__GetVolumeFromDistance(fDistance));
|
|
||||||
|
|
||||||
|
|
||||||
m_sounds3d.emplace_back(sample);
|
|
||||||
m_sounds3d.back().SetFile(file);
|
|
||||||
m_sounds3d.back().SetPosition((fx - m_fxPosition) / m_fSoundScale,
|
|
||||||
(fy - m_fyPosition) / m_fSoundScale,
|
|
||||||
(fz - m_fzPosition) / m_fSoundScale);
|
|
||||||
m_sounds3d.back().SetVolume(__GetVolumeFromDistance(fDistance));
|
|
||||||
m_sounds3d.back().Play(iPlayCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<SoundSample> CSoundManager::PlayAmbienceSound3D(float fx, float fy, float fz, std::string_view filename,
|
|
||||||
int iPlayCount)
|
|
||||||
{
|
|
||||||
if (0.0f == GetSoundVolume())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (m_sounds3d.size() >= m_max3dSoundsPlaying)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
const auto file = m_cache.Get(filename);
|
|
||||||
if (!file)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (!m_driver)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
const auto sample = AIL_allocate_sample_handle(m_driver);
|
|
||||||
if (!sample)
|
|
||||||
{
|
|
||||||
Tracenf("AIL_allocate_sample_handle(): %s for %s", AIL_last_error(), filename.data());
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto sound = std::make_unique<SoundSample>(sample);
|
|
||||||
sound->SetFile(file);
|
|
||||||
sound->SetPosition((fx - m_fxPosition) / m_fSoundScale,
|
|
||||||
(fy - m_fyPosition) / m_fSoundScale,
|
|
||||||
(fz - m_fzPosition) / m_fSoundScale);
|
|
||||||
sound->SetVolume(GetSoundVolume());
|
|
||||||
sound->Play(iPlayCount);
|
|
||||||
|
|
||||||
return sound;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::PlayCharacterSound3D(float fx, float fy, float fz, const std::string &filename,
|
|
||||||
bool bCheckFrequency)
|
|
||||||
{
|
|
||||||
if (0.0f == GetSoundVolume())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 어느 정도의 최적화가 필요할 수도 있다 - [levites]
|
|
||||||
if (bCheckFrequency)
|
|
||||||
{
|
|
||||||
static float s_fLimitDistance = 5000 * 5000;
|
|
||||||
float fdx = (fx - m_fxPosition) * (fx - m_fxPosition);
|
|
||||||
float fdy = (fy - m_fyPosition) * (fy - m_fyPosition);
|
|
||||||
|
|
||||||
if (fdx + fdy > s_fLimitDistance)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto itor = m_playSoundHistoryMap.find(filename);
|
|
||||||
if (m_playSoundHistoryMap.end() != itor)
|
|
||||||
{
|
|
||||||
float fTime = itor->second;
|
|
||||||
if (CTimer::instance().GetCurrentSecond() - fTime < 0.3f)
|
|
||||||
//if (DX::StepTimer::instance().GetTotalSeconds() - fTime < 0.3f)
|
|
||||||
{
|
|
||||||
// Tracef("똑같은 소리가 0.3초 내에 다시 플레이 %s\n", filename);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_playSoundHistoryMap.erase(itor);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_playSoundHistoryMap.emplace(filename, CTimer::instance().GetCurrentSecond());
|
|
||||||
//m_playSoundHistoryMap.emplace(filename, DX::StepTimer::instance().GetTotalSeconds());
|
|
||||||
}
|
|
||||||
|
|
||||||
Tracenf("Playing sound %s", filename.data());
|
|
||||||
PlaySound3D(fx, fy, fz, filename, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::StopAllSound3D()
|
|
||||||
{
|
|
||||||
m_sounds3d.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::FadeInMusic(const std::string &filename, float fVolumeSpeed)
|
|
||||||
{
|
|
||||||
const auto it = m_music.find(filename);
|
|
||||||
if (it != m_music.end())
|
|
||||||
{
|
|
||||||
it->second.MusicState = MUSIC_STATE_FADE_IN;
|
|
||||||
it->second.fVolumeSpeed = fVolumeSpeed;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_music.size() >= m_maxMusicPlaying)
|
|
||||||
return;
|
|
||||||
|
|
||||||
FadeOutAllMusic();
|
|
||||||
|
|
||||||
if (!m_driver)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto stream = AIL_open_stream(m_driver, filename.c_str(), 0);
|
|
||||||
if (!stream)
|
|
||||||
{
|
|
||||||
Tracenf("AIL_open_stream(%s): %s", filename.c_str(), AIL_last_error());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_music.emplace(std::piecewise_construct, std::forward_as_tuple(filename),
|
|
||||||
std::forward_as_tuple(stream, filename, 0.0f, fVolumeSpeed));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::FadeLimitOutMusic(const std::string &filename, float fLimitVolume, float fVolumeSpeed)
|
|
||||||
{
|
|
||||||
const auto it = m_music.find(filename);
|
|
||||||
if (it == m_music.end())
|
|
||||||
{
|
|
||||||
Tracenf("FadeLimitOutMusic: %s is not being played", filename.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
it->second.MusicState = MUSIC_STATE_FADE_LIMIT_OUT;
|
|
||||||
it->second.fVolumeSpeed = fVolumeSpeed;
|
|
||||||
it->second.fLimitVolume = fLimitVolume;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::FadeOutMusic(const std::string &filename, float fVolumeSpeed)
|
|
||||||
{
|
|
||||||
const auto it = m_music.find(filename);
|
|
||||||
if (it == m_music.end())
|
|
||||||
{
|
|
||||||
Tracenf("FadeOutMusic: %s is not being played", filename.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
it->second.MusicState = MUSIC_STATE_FADE_OUT;
|
|
||||||
it->second.fVolumeSpeed = fVolumeSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CSoundManager::FadeOutAllMusic()
|
|
||||||
{
|
|
||||||
for (auto &p : m_music)
|
|
||||||
{
|
|
||||||
if (MUSIC_STATE_OFF == p.second.MusicState)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
p.second.MusicState = MUSIC_STATE_FADE_OUT;
|
|
||||||
p.second.fVolumeSpeed = 0.01f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "EterBase/Singleton.h"
|
|
||||||
#include "SampleFileCache.hpp"
|
|
||||||
#include "MusicInstance.hpp"
|
|
||||||
#include "SoundSample.hpp"
|
|
||||||
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
struct MilesLibrary
|
|
||||||
{
|
|
||||||
MilesLibrary();
|
|
||||||
~MilesLibrary();
|
|
||||||
};
|
|
||||||
|
|
||||||
class CSoundManager : public CSingleton<CSoundManager>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CSoundManager();
|
|
||||||
|
|
||||||
bool Create();
|
|
||||||
|
|
||||||
void SetPosition(float fx, float fy, float fz);
|
|
||||||
void SetDirection(float fxDir, float fyDir, float fzDir, float fxUp, float fyUp, float fzUp);
|
|
||||||
void Update();
|
|
||||||
|
|
||||||
float GetSoundScale();
|
|
||||||
void SetSoundScale(float fScale);
|
|
||||||
void SetAmbienceSoundScale(float fScale);
|
|
||||||
|
|
||||||
void SetSoundVolume(float fVolume);
|
|
||||||
void SetMusicVolume(float fVolume);
|
|
||||||
|
|
||||||
void SaveVolume();
|
|
||||||
void RestoreVolume();
|
|
||||||
|
|
||||||
float GetSoundVolume();
|
|
||||||
float GetMusicVolume();
|
|
||||||
|
|
||||||
// Sound
|
|
||||||
void PlaySound2D(std::string_view filename);
|
|
||||||
float __GetVolumeFromDistance(float fDistance);
|
|
||||||
void PlaySound3D(float fx, float fy, float fz,
|
|
||||||
std::string_view filename,
|
|
||||||
int iPlayCount = 1);
|
|
||||||
std::unique_ptr<SoundSample> PlayAmbienceSound3D(float fx, float fy, float fz,
|
|
||||||
std::string_view filename,
|
|
||||||
int iPlayCount = 1);
|
|
||||||
void PlayCharacterSound3D(float fx, float fy, float fz,
|
|
||||||
const std::string &filename,
|
|
||||||
bool bCheckFrequency = false);
|
|
||||||
void StopAllSound3D();
|
|
||||||
|
|
||||||
// Music
|
|
||||||
void FadeInMusic(const std::string &filename,
|
|
||||||
float fVolumeSpeed = 0.016f);
|
|
||||||
void FadeOutMusic(const std::string &filename,
|
|
||||||
float fVolumeSpeed = 0.016f);
|
|
||||||
void FadeLimitOutMusic(const std::string &filename,
|
|
||||||
float fLimitVolume, float fVolumeSpeed = 0.016f);
|
|
||||||
void FadeOutAllMusic();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
MilesLibrary m_miles;
|
|
||||||
bool m_isSoundDisable;
|
|
||||||
|
|
||||||
uint32_t m_max2dSoundsPlaying;
|
|
||||||
uint32_t m_max3dSoundsPlaying;
|
|
||||||
uint32_t m_maxMusicPlaying;
|
|
||||||
|
|
||||||
float m_fxPosition;
|
|
||||||
float m_fyPosition;
|
|
||||||
float m_fzPosition;
|
|
||||||
|
|
||||||
float m_fSoundScale;
|
|
||||||
float m_fAmbienceSoundScale;
|
|
||||||
float m_fSoundVolume;
|
|
||||||
float m_fMusicVolume;
|
|
||||||
|
|
||||||
float m_fBackupMusicVolume;
|
|
||||||
float m_fBackupSoundVolume;
|
|
||||||
|
|
||||||
HDIGDRIVER m_driver;
|
|
||||||
|
|
||||||
SampleFileCache m_cache;
|
|
||||||
std::unordered_map<std::string, MusicInstance> m_music;
|
|
||||||
std::vector<SoundSample> m_sounds2d;
|
|
||||||
std::vector<SoundSample> m_sounds3d;
|
|
||||||
std::unordered_map<std::string, float> m_playSoundHistoryMap;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
#include "Stdafx.h"
|
|
||||||
#include "SoundSample.hpp"
|
|
||||||
|
|
||||||
#include "../EterBase/Debug.h"
|
|
||||||
#include "../EterBase/Timer.h"
|
|
||||||
#include "../EterBase/Utils.h"
|
|
||||||
|
|
||||||
SoundSample::SoundSample(HSAMPLE sample) : m_sample(sample)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SoundSample::SoundSample(SoundSample &&other) : m_sample(other.m_sample), m_sampleFile(std::move(other.m_sampleFile))
|
|
||||||
{
|
|
||||||
other.m_sample = nullptr;
|
|
||||||
other.m_sampleFile.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
SoundSample::~SoundSample()
|
|
||||||
{
|
|
||||||
if (m_sample)
|
|
||||||
{
|
|
||||||
AIL_release_sample_handle(m_sample);
|
|
||||||
m_sample = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SoundSample &SoundSample::operator=(SoundSample &&other)
|
|
||||||
{
|
|
||||||
if (this == &other)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
if (m_sample)
|
|
||||||
AIL_release_sample_handle(m_sample);
|
|
||||||
|
|
||||||
m_sample = other.m_sample;
|
|
||||||
other.m_sample = nullptr;
|
|
||||||
|
|
||||||
m_sampleFile = std::move(other.m_sampleFile);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SoundSample::SetFile(SampleFilePtr sample)
|
|
||||||
{
|
|
||||||
if (!AIL_set_named_sample_file(m_sample, sample->GetFilename().c_str(), sample->GetData(), sample->GetSize(), 0))
|
|
||||||
{
|
|
||||||
Tracenf("%s: %s", sample->GetFilename().c_str(), AIL_last_error());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sampleFile = std::move(sample);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SoundSample::IsDone() const
|
|
||||||
{
|
|
||||||
return AIL_sample_status(m_sample) == SMP_DONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundSample::Play(int loopCount) const
|
|
||||||
{
|
|
||||||
//AIL_set_sample_3D_distances(m_sample, 5000.0f, -1.0f, 0);
|
|
||||||
AIL_set_sample_loop_count(m_sample, loopCount);
|
|
||||||
AIL_start_sample(m_sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundSample::Pause() const
|
|
||||||
{
|
|
||||||
AIL_stop_sample(m_sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundSample::Resume() const
|
|
||||||
{
|
|
||||||
AIL_resume_sample(m_sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundSample::Stop() const
|
|
||||||
{
|
|
||||||
AIL_end_sample(m_sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
float SoundSample::GetVolume() const
|
|
||||||
{
|
|
||||||
float volume;
|
|
||||||
AIL_sample_volume_pan(m_sample, &volume, nullptr);
|
|
||||||
return volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundSample::SetVolume(float volume) const
|
|
||||||
{
|
|
||||||
volume = std::max<float>(0.0f, std::min<float>(1.0f, volume));
|
|
||||||
AIL_set_sample_volume_pan(m_sample, volume, 0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundSample::SetPosition(float x, float y, float z) const
|
|
||||||
{
|
|
||||||
//AIL_set_sample_3D_position(m_sample, x, y, -z);
|
|
||||||
// AIL_set_sample_is_3D(m_sample, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundSample::SetVelocity(float fDistanceX, float fDistanceY, float fDistanceZ, float fNagnitude) const
|
|
||||||
{
|
|
||||||
AIL_set_sample_3D_velocity(m_sample, fDistanceX, fDistanceY, fDistanceZ, fNagnitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundSample::UpdatePosition(float fElapsedTime)
|
|
||||||
{
|
|
||||||
AIL_update_sample_3D_position(m_sample, fElapsedTime);
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "SampleFile.hpp"
|
|
||||||
#include <mss.h>
|
|
||||||
|
|
||||||
class SoundSample
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SoundSample(HSAMPLE sample);
|
|
||||||
SoundSample(SoundSample &&other);
|
|
||||||
SoundSample(const SoundSample &other) = delete;
|
|
||||||
~SoundSample();
|
|
||||||
|
|
||||||
SoundSample &operator=(SoundSample &&other);
|
|
||||||
SoundSample &operator=(const SoundSample &other) = delete;
|
|
||||||
|
|
||||||
bool SetFile(SampleFilePtr sample);
|
|
||||||
|
|
||||||
void Play(int loopCount = 1) const;
|
|
||||||
void Pause() const;
|
|
||||||
void Resume() const;
|
|
||||||
void Stop() const;
|
|
||||||
float GetVolume() const;
|
|
||||||
void SetVolume(float volume) const;
|
|
||||||
bool IsDone() const;
|
|
||||||
|
|
||||||
void SetPosition(float x, float y, float z) const;
|
|
||||||
void SetVelocity(float fx, float fy, float fz, float fMagnitude) const;
|
|
||||||
|
|
||||||
void UpdatePosition(float fElapsedTime);
|
|
||||||
|
|
||||||
private:
|
|
||||||
HSAMPLE m_sample;
|
|
||||||
SampleFilePtr m_sampleFile;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
#include "Stdafx.h"
|
|
||||||
#include "SoundStream.hpp"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
SoundStream::SoundStream(HSTREAM stream)
|
|
||||||
: m_stream(stream)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
SoundStream::~SoundStream()
|
|
||||||
{
|
|
||||||
if (m_stream)
|
|
||||||
{
|
|
||||||
AIL_close_stream(m_stream);
|
|
||||||
m_stream = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SoundStream::IsDone() const
|
|
||||||
{
|
|
||||||
return AIL_stream_status(m_stream) == -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundStream::Play(int loopCount) const
|
|
||||||
{
|
|
||||||
AIL_set_stream_loop_count(m_stream, loopCount);
|
|
||||||
AIL_start_stream(m_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundStream::Pause() const
|
|
||||||
{
|
|
||||||
AIL_pause_stream(m_stream, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundStream::Resume() const
|
|
||||||
{
|
|
||||||
AIL_pause_stream(m_stream, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundStream::Stop()
|
|
||||||
{
|
|
||||||
AIL_close_stream(m_stream);
|
|
||||||
m_stream = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SoundStream::GetVolume() const
|
|
||||||
{
|
|
||||||
const auto sample = AIL_stream_sample_handle(m_stream);
|
|
||||||
if (!sample)
|
|
||||||
return 0.0f;
|
|
||||||
|
|
||||||
F32 volume;
|
|
||||||
AIL_sample_volume_pan(sample, &volume, nullptr);
|
|
||||||
return volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundStream::SetVolume(float volume) const
|
|
||||||
{
|
|
||||||
const auto sample = AIL_stream_sample_handle(m_stream);
|
|
||||||
if (!sample)
|
|
||||||
return;
|
|
||||||
|
|
||||||
volume = std::max<float>(0.0f, std::min<float>(1.0f, volume));
|
|
||||||
AIL_set_sample_volume_pan(sample, volume, 0.5f);
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mss.h>
|
|
||||||
|
|
||||||
class SoundStream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SoundStream(HSTREAM stream);
|
|
||||||
~SoundStream();
|
|
||||||
|
|
||||||
SoundStream(const SoundStream&) = delete;
|
|
||||||
void operator=(const SoundStream&) = delete;
|
|
||||||
|
|
||||||
void Play(int loopCount = 1) const;
|
|
||||||
void Pause() const;
|
|
||||||
void Resume() const;
|
|
||||||
void Stop();
|
|
||||||
float GetVolume() const;
|
|
||||||
void SetVolume(float volume) const;
|
|
||||||
bool IsDone() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
HSTREAM m_stream;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "EterBase/StdAfx.h"
|
|
||||||
|
|
||||||
#include <mss.h>
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
#include "Stdafx.h"
|
|
||||||
#include "Type.h"
|
|
||||||
#include "SoundManager.h"
|
|
||||||
|
|
||||||
#include "../EterBase/Debug.h"
|
|
||||||
#include "../EterLib/TextFileLoader.h"
|
|
||||||
#include "../EterLib/Util.h"
|
|
||||||
|
|
||||||
bool LoadSoundInformationPiece(const char *c_szFileName,
|
|
||||||
TSoundDataVector &rSoundDataVector,
|
|
||||||
const char *c_szPathHeader)
|
|
||||||
{
|
|
||||||
CTextFileLoader *pkTextFileLoader = CTextFileLoader::Cache(c_szFileName);
|
|
||||||
if (!pkTextFileLoader)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CTextFileLoader &rkTextFileLoader = *pkTextFileLoader;
|
|
||||||
if (rkTextFileLoader.IsEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
rkTextFileLoader.SetTop();
|
|
||||||
|
|
||||||
int iCount;
|
|
||||||
if (!rkTextFileLoader.GetTokenInteger("sounddatacount", &iCount))
|
|
||||||
{
|
|
||||||
Tracenf("%s: no SoundDataCount", c_szFileName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rSoundDataVector.clear();
|
|
||||||
rSoundDataVector.resize(iCount);
|
|
||||||
|
|
||||||
char szSoundDataHeader[32 + 1];
|
|
||||||
for (uint32_t i = 0; i < rSoundDataVector.size(); ++i)
|
|
||||||
{
|
|
||||||
_snprintf(szSoundDataHeader, sizeof(szSoundDataHeader), "sounddata%02d", i);
|
|
||||||
CTokenVector *pTokenVector;
|
|
||||||
if (!rkTextFileLoader.GetTokenVector(szSoundDataHeader, &pTokenVector))
|
|
||||||
{
|
|
||||||
Tracenf("%s: no %s", c_szFileName, szSoundDataHeader);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (2 != pTokenVector->size())
|
|
||||||
{
|
|
||||||
Tracenf("%s: %s has wrong size %u", c_szFileName,
|
|
||||||
szSoundDataHeader, pTokenVector->size());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rSoundDataVector[i].fTime = (float)atof(pTokenVector->at(0).c_str());
|
|
||||||
if (c_szPathHeader)
|
|
||||||
{
|
|
||||||
rSoundDataVector[i].strSoundFileName = c_szPathHeader;
|
|
||||||
rSoundDataVector[i].strSoundFileName += pTokenVector->at(1).c_str();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rSoundDataVector[i].strSoundFileName = pTokenVector->at(1).c_str();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SaveSoundInformationPiece(const char *c_szFileName, TSoundDataVector &rSoundDataVector)
|
|
||||||
{
|
|
||||||
/*storm::String realFilename;
|
|
||||||
GetVfs().GetPathTranslator().Translate(c_szFileName, realFilename);
|
|
||||||
|
|
||||||
if (rSoundDataVector.empty()) // 데이터가 없으면 성공으로 간주
|
|
||||||
{
|
|
||||||
::DeleteFileA(realFilename.c_str());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
storm::File File;
|
|
||||||
|
|
||||||
bsys::error_code ec;
|
|
||||||
File.Open(realFilename, ec,
|
|
||||||
storm::AccessMode::kWrite,
|
|
||||||
storm::CreationDisposition::kCreateAlways,
|
|
||||||
storm::ShareMode::kNone,
|
|
||||||
storm::UsageHint::kSequential);
|
|
||||||
|
|
||||||
if (ec) {
|
|
||||||
SPDLOG_ERROR("Failed to open {0} for writing with {1}",
|
|
||||||
realFilename, ec);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintfTabs(File, 0, "ScriptType CharacterSoundInformation\n");
|
|
||||||
PrintfTabs(File, 0, "\n");
|
|
||||||
|
|
||||||
PrintfTabs(File, 0, "SoundDataCount %d\n", rSoundDataVector.size());
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < rSoundDataVector.size(); ++i)
|
|
||||||
{
|
|
||||||
const auto & rSoundData = rSoundDataVector[i];
|
|
||||||
PrintfTabs(File, 0, "SoundData%02d %f \"%s\"\n",
|
|
||||||
i, rSoundData.fTime,
|
|
||||||
rSoundData.strSoundFileName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataToInstance(const TSoundDataVector &c_rSoundDataVector, TSoundInstanceVector *pSoundInstanceVector)
|
|
||||||
{
|
|
||||||
if (c_rSoundDataVector.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const float c_fFrameTime = 1.0f / 60.0f;
|
|
||||||
|
|
||||||
pSoundInstanceVector->clear();
|
|
||||||
pSoundInstanceVector->resize(c_rSoundDataVector.size());
|
|
||||||
for (uint32_t i = 0; i < c_rSoundDataVector.size(); ++i)
|
|
||||||
{
|
|
||||||
const TSoundData &c_rSoundData = c_rSoundDataVector[i];
|
|
||||||
TSoundInstance &rSoundInstance = pSoundInstanceVector->at(i);
|
|
||||||
|
|
||||||
rSoundInstance.dwFrame = (uint32_t)(c_rSoundData.fTime / c_fFrameTime);
|
|
||||||
rSoundInstance.strSoundFileName = c_rSoundData.strSoundFileName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateSoundInstance(uint32_t frame, const TSoundInstanceVector &sounds,
|
|
||||||
float fx, float fy, float fz, bool bCheckFrequency)
|
|
||||||
{
|
|
||||||
auto &snd = CSoundManager::Instance();
|
|
||||||
for (const auto &instance : sounds)
|
|
||||||
{
|
|
||||||
if (instance.dwFrame != frame)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
snd.PlayCharacterSound3D(fx, fy, fz,
|
|
||||||
instance.strSoundFileName,
|
|
||||||
bCheckFrequency);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateSoundInstance(uint32_t frame, const TSoundInstanceVector &sounds)
|
|
||||||
{
|
|
||||||
for (const auto &instance : sounds)
|
|
||||||
{
|
|
||||||
if (instance.dwFrame == frame)
|
|
||||||
CSoundManager::Instance().PlaySound2D(instance.strSoundFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#ifndef METIN2_CLIENT_MILESLIB_TYPE_HPP
|
|
||||||
#define METIN2_CLIENT_MILESLIB_TYPE_HPP
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
typedef struct SSoundData
|
|
||||||
{
|
|
||||||
float fTime;
|
|
||||||
std::string strSoundFileName;
|
|
||||||
} TSoundData;
|
|
||||||
|
|
||||||
typedef struct SSoundInstance
|
|
||||||
{
|
|
||||||
uint32_t dwFrame;
|
|
||||||
std::string strSoundFileName;
|
|
||||||
} TSoundInstance;
|
|
||||||
|
|
||||||
typedef std::vector<TSoundData> TSoundDataVector;
|
|
||||||
typedef std::vector<TSoundInstance> TSoundInstanceVector;
|
|
||||||
|
|
||||||
bool LoadSoundInformationPiece(const char *c_szFileName,
|
|
||||||
TSoundDataVector &rSoundDataVector,
|
|
||||||
const char *c_szPathHeader = NULL);
|
|
||||||
bool SaveSoundInformationPiece(const char *c_szFileName,
|
|
||||||
TSoundDataVector &rSoundDataVector);
|
|
||||||
|
|
||||||
void DataToInstance(const TSoundDataVector &c_rSoundDataVector,
|
|
||||||
TSoundInstanceVector *pSoundInstanceVector);
|
|
||||||
|
|
||||||
void UpdateSoundInstance(uint32_t frame, const TSoundInstanceVector &sounds,
|
|
||||||
float fx, float fy, float fz, bool bCheckFrequency);
|
|
||||||
|
|
||||||
void UpdateSoundInstance(uint32_t frame, const TSoundInstanceVector &sounds);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -9,6 +9,7 @@ set_target_properties(UserInterface PROPERTIES LINK_FLAGS "/level='requireAdmini
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(UserInterface
|
target_link_libraries(UserInterface
|
||||||
|
AudioLib
|
||||||
Discord
|
Discord
|
||||||
EffectLib
|
EffectLib
|
||||||
EterBase
|
EterBase
|
||||||
@@ -19,7 +20,6 @@ target_link_libraries(UserInterface
|
|||||||
EterPack
|
EterPack
|
||||||
EterPythonLib
|
EterPythonLib
|
||||||
GameLib
|
GameLib
|
||||||
MilesLib
|
|
||||||
PRTerrainLib
|
PRTerrainLib
|
||||||
ScriptLib
|
ScriptLib
|
||||||
SpeedTreeLib
|
SpeedTreeLib
|
||||||
@@ -31,7 +31,6 @@ target_link_libraries(UserInterface
|
|||||||
DirectX
|
DirectX
|
||||||
Granny
|
Granny
|
||||||
SpeedTree
|
SpeedTree
|
||||||
MilesSoundSystem
|
|
||||||
Python
|
Python
|
||||||
WebView
|
WebView
|
||||||
|
|
||||||
|
|||||||
@@ -1051,10 +1051,10 @@ bool CPythonApplication::Create(PyObject * poSelf, const char * c_szName, int wi
|
|||||||
if (!m_pySystem.IsNoSoundCard())
|
if (!m_pySystem.IsNoSoundCard())
|
||||||
{
|
{
|
||||||
// Sound
|
// Sound
|
||||||
if (!m_SoundManager.Create())
|
if (!m_SoundEngine.Initialize())
|
||||||
{
|
{
|
||||||
// NOTE : Áß±¹ÃøÀÇ ¿äûÀ¸·Î »ý·«
|
TraceError("Failed to initialize sound manager!");
|
||||||
// LogBox(ApplicationStringTable_GetStringz(IDS_WARN_NO_SOUND_DEVICE));
|
return false; // Is this important enough to stop the client?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "gamelib/ItemManager.h"
|
#include "gamelib/ItemManager.h"
|
||||||
#include "gamelib/FlyingObjectManager.h"
|
#include "gamelib/FlyingObjectManager.h"
|
||||||
#include "gamelib/GameEventManager.h"
|
#include "gamelib/GameEventManager.h"
|
||||||
#include "milesLib/SoundManager.h"
|
#include "AudioLib/SoundEngine.h"
|
||||||
|
|
||||||
#include "PythonEventManager.h"
|
#include "PythonEventManager.h"
|
||||||
#include "PythonPlayer.h"
|
#include "PythonPlayer.h"
|
||||||
@@ -310,7 +310,7 @@ class CPythonApplication : public CMSApplication, public CInputKeyboard, public
|
|||||||
CTimer m_timer;
|
CTimer m_timer;
|
||||||
|
|
||||||
CLightManager m_LightManager;
|
CLightManager m_LightManager;
|
||||||
CSoundManager m_SoundManager;
|
SoundEngine m_SoundEngine;
|
||||||
CFlyingManager m_FlyingManager;
|
CFlyingManager m_FlyingManager;
|
||||||
CRaceManager m_RaceManager;
|
CRaceManager m_RaceManager;
|
||||||
CGameEventManager m_GameEventManager;
|
CGameEventManager m_GameEventManager;
|
||||||
|
|||||||
@@ -91,9 +91,9 @@ void CPythonApplication::__UpdateCamera()
|
|||||||
// Sound Setting
|
// Sound Setting
|
||||||
const D3DXVECTOR3 & c_rv3CameraDirection = pMainCamera->GetView();
|
const D3DXVECTOR3 & c_rv3CameraDirection = pMainCamera->GetView();
|
||||||
const D3DXVECTOR3 & c_rv3CameraUp = pMainCamera->GetUp();
|
const D3DXVECTOR3 & c_rv3CameraUp = pMainCamera->GetUp();
|
||||||
m_SoundManager.SetPosition(m_v3CenterPosition.x, m_v3CenterPosition.y, m_v3CenterPosition.z); // Listener - 캐릭터 위치
|
m_SoundEngine.SetListenerPosition(m_v3CenterPosition.x, m_v3CenterPosition.y, m_v3CenterPosition.z); // Listener - 캐릭터 위치
|
||||||
m_SoundManager.SetDirection(c_rv3CameraDirection.x, c_rv3CameraDirection.y, c_rv3CameraDirection.z, c_rv3CameraUp.x, c_rv3CameraUp.y, c_rv3CameraUp.z);
|
m_SoundEngine.SetListenerOrientation(c_rv3CameraDirection.x, c_rv3CameraDirection.y, c_rv3CameraDirection.z, c_rv3CameraUp.x, c_rv3CameraUp.y, c_rv3CameraUp.z);
|
||||||
m_SoundManager.Update();
|
m_SoundEngine.Update();
|
||||||
//////////////////////
|
//////////////////////
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ LRESULT CPythonApplication::WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam
|
|||||||
|
|
||||||
if (m_isActivateWnd)
|
if (m_isActivateWnd)
|
||||||
{
|
{
|
||||||
m_SoundManager.RestoreVolume();
|
m_SoundEngine.RestoreVolume();
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ LRESULT CPythonApplication::WindowProcedure(HWND hWnd, UINT uiMsg, WPARAM wParam
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_SoundManager.SaveVolume();
|
m_SoundEngine.SaveVolume(m_isMinimizedWnd);
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ void CPythonItem::TGroundItemInstance::__PlayDropSound(DWORD eItemType, const D3
|
|||||||
if (eItemType>=DROPSOUND_NUM)
|
if (eItemType>=DROPSOUND_NUM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CSoundManager::Instance().PlaySound3D(c_rv3Pos.x, c_rv3Pos.y, c_rv3Pos.z, ms_astDropSoundFileName[eItemType].c_str());
|
SoundEngine::Instance().PlaySound3D(ms_astDropSoundFileName[eItemType].c_str(), c_rv3Pos.x, c_rv3Pos.y, c_rv3Pos.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPythonItem::TGroundItemInstance::Update()
|
bool CPythonItem::TGroundItemInstance::Update()
|
||||||
@@ -165,7 +165,7 @@ void CPythonItem::PlayUseSound(DWORD dwItemID)
|
|||||||
if (eItemType>=USESOUND_NUM)
|
if (eItemType>=USESOUND_NUM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CSoundManager::Instance().PlaySound2D(m_astUseSoundFileName[eItemType].c_str());
|
SoundEngine::Instance().PlaySound2D(m_astUseSoundFileName[eItemType].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -181,12 +181,12 @@ void CPythonItem::PlayDropSound(DWORD dwItemID)
|
|||||||
if (eItemType>=DROPSOUND_NUM)
|
if (eItemType>=DROPSOUND_NUM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CSoundManager::Instance().PlaySound2D(SGroundItemInstance::ms_astDropSoundFileName[eItemType].c_str());
|
SoundEngine::Instance().PlaySound2D(SGroundItemInstance::ms_astDropSoundFileName[eItemType].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPythonItem::PlayUsePotionSound()
|
void CPythonItem::PlayUsePotionSound()
|
||||||
{
|
{
|
||||||
CSoundManager::Instance().PlaySound2D(m_astUseSoundFileName[USESOUND_POTION].c_str());
|
SoundEngine::Instance().PlaySound2D(m_astUseSoundFileName[USESOUND_POTION].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD CPythonItem::__GetDropSoundType(const CItemData& c_rkItemData)
|
DWORD CPythonItem::__GetDropSoundType(const CItemData& c_rkItemData)
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "PythonApplication.h"
|
#include "PythonApplication.h"
|
||||||
|
|
||||||
PyObject * sndPlaySound(PyObject * poSelf, PyObject * poArgs)
|
PyObject* sndPlaySound2D(PyObject* poSelf, PyObject* poArgs)
|
||||||
{
|
{
|
||||||
char * szFileName;
|
char* szFileName;
|
||||||
if (!PyTuple_GetString(poArgs, 0, &szFileName))
|
if (!PyTuple_GetString(poArgs, 0, &szFileName))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
SoundEngine::Instance().PlaySound2D(szFileName);
|
||||||
rkSndMgr.PlaySound2D(szFileName);
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * sndPlaySound3D(PyObject * poSelf, PyObject * poArgs)
|
PyObject* sndPlaySound3D(PyObject* poSelf, PyObject* poArgs)
|
||||||
{
|
{
|
||||||
float fx;
|
float fx;
|
||||||
if (!PyTuple_GetFloat(poArgs, 0, &fx))
|
if (!PyTuple_GetFloat(poArgs, 0, &fx))
|
||||||
@@ -23,58 +22,43 @@ PyObject * sndPlaySound3D(PyObject * poSelf, PyObject * poArgs)
|
|||||||
float fz;
|
float fz;
|
||||||
if (!PyTuple_GetFloat(poArgs, 2, &fz))
|
if (!PyTuple_GetFloat(poArgs, 2, &fz))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
char * szFileName;
|
char* szFileName;
|
||||||
if (!PyTuple_GetString(poArgs, 3, &szFileName))
|
if (!PyTuple_GetString(poArgs, 3, &szFileName))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
SoundEngine::Instance().PlaySound3D(szFileName, fx, fy, fz);
|
||||||
rkSndMgr.PlaySound3D(fx, fy, fz, szFileName);
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * sndPlayMusic(PyObject * poSelf, PyObject * poArgs)
|
PyObject* sndFadeInMusic(PyObject* poSelf, PyObject* poArgs)
|
||||||
{
|
{
|
||||||
char * szFileName;
|
char* szFileName;
|
||||||
if (!PyTuple_GetString(poArgs, 0, &szFileName))
|
if (!PyTuple_GetString(poArgs, 0, &szFileName))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
SoundEngine::Instance().FadeInMusic(szFileName);
|
||||||
rkSndMgr.PlaySound2D(szFileName);
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * sndFadeInMusic(PyObject * poSelf, PyObject * poArgs)
|
PyObject* sndFadeOutMusic(PyObject* poSelf, PyObject* poArgs)
|
||||||
{
|
{
|
||||||
char * szFileName;
|
char* szFileName;
|
||||||
if (!PyTuple_GetString(poArgs, 0, &szFileName))
|
if (!PyTuple_GetString(poArgs, 0, &szFileName))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
SoundEngine::Instance().FadeOutMusic(szFileName);
|
||||||
rkSndMgr.FadeInMusic(szFileName);
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * sndFadeOutMusic(PyObject * poSelf, PyObject * poArgs)
|
PyObject* sndFadeOutAllMusic(PyObject* poSelf, PyObject* poArgs)
|
||||||
{
|
{
|
||||||
char * szFileName;
|
SoundEngine::Instance().FadeOutAllMusic();
|
||||||
if (!PyTuple_GetString(poArgs, 0, &szFileName))
|
|
||||||
return Py_BuildException();
|
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
|
||||||
rkSndMgr.FadeOutMusic(szFileName);
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * sndFadeOutAllMusic(PyObject * poSelf, PyObject * poArgs)
|
PyObject* sndFadeLimitOutMusic(PyObject* poSelf, PyObject* poArgs)
|
||||||
{
|
{
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
char* szFileName;
|
||||||
rkSndMgr.FadeOutAllMusic();
|
|
||||||
return Py_BuildNone();
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject * sndFadeLimitOutMusic(PyObject * poSelf, PyObject * poArgs)
|
|
||||||
{
|
|
||||||
char * szFileName;
|
|
||||||
if (!PyTuple_GetString(poArgs, 0, &szFileName))
|
if (!PyTuple_GetString(poArgs, 0, &szFileName))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
|
|
||||||
@@ -82,95 +66,74 @@ PyObject * sndFadeLimitOutMusic(PyObject * poSelf, PyObject * poArgs)
|
|||||||
if (!PyTuple_GetFloat(poArgs, 1, &fLimitVolume))
|
if (!PyTuple_GetFloat(poArgs, 1, &fLimitVolume))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
SoundEngine::Instance().FadeOutMusic(szFileName, fLimitVolume);
|
||||||
rkSndMgr.FadeLimitOutMusic(szFileName, fLimitVolume);
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * sndStopAllSound(PyObject * poSelf, PyObject * poArgs)
|
PyObject* sndStopAllSound(PyObject* poSelf, PyObject* poArgs)
|
||||||
{
|
{
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
SoundEngine::Instance().StopAllSound3D();
|
||||||
rkSndMgr.StopAllSound3D();
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * sndSetMusicVolume(PyObject * poSelf, PyObject * poArgs)
|
PyObject* sndSetMasterVolume(PyObject* poSelf, PyObject* poArgs)
|
||||||
{
|
{
|
||||||
float fVolume;
|
float fVolume;
|
||||||
if (!PyTuple_GetFloat(poArgs, 0, &fVolume))
|
if (!PyTuple_GetFloat(poArgs, 0, &fVolume))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
SoundEngine::Instance().SetMasterVolume(fVolume);
|
||||||
rkSndMgr.SetMusicVolume(fVolume);
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * sndSetSoundVolumef(PyObject * poSelf, PyObject * poArgs)
|
PyObject* sndSetMusicVolume(PyObject* poSelf, PyObject* poArgs)
|
||||||
{
|
{
|
||||||
float fVolume;
|
float fVolume;
|
||||||
if (!PyTuple_GetFloat(poArgs, 0, &fVolume))
|
if (!PyTuple_GetFloat(poArgs, 0, &fVolume))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
SoundEngine::Instance().SetMusicVolume(fVolume);
|
||||||
rkSndMgr.SetSoundVolume(fVolume);
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject* sndSetSoundVolumef(PyObject* poSelf, PyObject* poArgs)
|
||||||
PyObject * sndSetSoundVolume(PyObject * poSelf, PyObject * poArgs)
|
|
||||||
{
|
{
|
||||||
int iVolume;
|
float fVolume;
|
||||||
if (!PyTuple_GetInteger(poArgs, 0, &iVolume))
|
if (!PyTuple_GetFloat(poArgs, 0, &fVolume))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
SoundEngine::Instance().SetSoundVolume(fVolume);
|
||||||
rkSndMgr.SetSoundVolume(iVolume);
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject * sndSetSoundScale(PyObject * poSelf, PyObject * poArgs)
|
PyObject* sndSetSoundVolume(PyObject* poSelf, PyObject* poArgs)
|
||||||
{
|
{
|
||||||
float fScale;
|
float volume;
|
||||||
if (!PyTuple_GetFloat(poArgs, 0, &fScale))
|
if (!PyTuple_GetFloat(poArgs, 0, &volume))
|
||||||
return Py_BuildException();
|
return Py_BuildException();
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
SoundEngine::Instance().SetSoundVolume(volume / 100.0f);
|
||||||
rkSndMgr.SetSoundScale(fScale);
|
|
||||||
return Py_BuildNone();
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject * sndSetAmbienceSoundScale(PyObject * poSelf, PyObject * poArgs)
|
|
||||||
{
|
|
||||||
float fScale;
|
|
||||||
if (!PyTuple_GetFloat(poArgs, 0, &fScale))
|
|
||||||
return Py_BuildException();
|
|
||||||
|
|
||||||
CSoundManager& rkSndMgr=CSoundManager::Instance();
|
|
||||||
rkSndMgr.SetAmbienceSoundScale(fScale);
|
|
||||||
return Py_BuildNone();
|
return Py_BuildNone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initsnd()
|
void initsnd()
|
||||||
{
|
{
|
||||||
static PyMethodDef s_methods[] =
|
static PyMethodDef s_methods[] =
|
||||||
{
|
{
|
||||||
{ "PlaySound", sndPlaySound, METH_VARARGS },
|
{ "PlaySound", sndPlaySound2D, METH_VARARGS },
|
||||||
{ "PlaySound3D", sndPlaySound3D, METH_VARARGS },
|
{ "PlaySound3D", sndPlaySound3D, METH_VARARGS },
|
||||||
{ "PlayMusic", sndPlayMusic, METH_VARARGS },
|
|
||||||
{ "FadeInMusic", sndFadeInMusic, METH_VARARGS },
|
{ "FadeInMusic", sndFadeInMusic, METH_VARARGS },
|
||||||
{ "FadeOutMusic", sndFadeOutMusic, METH_VARARGS },
|
{ "FadeOutMusic", sndFadeOutMusic, METH_VARARGS },
|
||||||
{ "FadeOutAllMusic", sndFadeOutAllMusic, METH_VARARGS },
|
{ "FadeOutAllMusic", sndFadeOutAllMusic, METH_VARARGS },
|
||||||
{ "FadeLimitOutMusic", sndFadeLimitOutMusic, METH_VARARGS },
|
{ "FadeLimitOutMusic", sndFadeLimitOutMusic, METH_VARARGS },
|
||||||
{ "StopAllSound", sndStopAllSound, METH_VARARGS },
|
{ "StopAllSound", sndStopAllSound, METH_VARARGS },
|
||||||
|
|
||||||
{ "SetMusicVolumef", sndSetMusicVolume, METH_VARARGS },
|
{ "SetMasterVolume", sndSetMasterVolume, METH_VARARGS },
|
||||||
{ "SetMusicVolume", sndSetMusicVolume, METH_VARARGS },
|
{ "SetMusicVolume", sndSetMusicVolume, METH_VARARGS },
|
||||||
{ "SetSoundVolumef", sndSetSoundVolumef, METH_VARARGS },
|
{ "SetSoundVolumef", sndSetSoundVolumef, METH_VARARGS },
|
||||||
{ "SetSoundVolume", sndSetSoundVolume, METH_VARARGS },
|
{ "SetSoundVolume", sndSetSoundVolume, METH_VARARGS },
|
||||||
{ "SetSoundScale", sndSetSoundScale, METH_VARARGS },
|
|
||||||
{ "SetAmbienceSoundScale", sndSetAmbienceSoundScale, METH_VARARGS },
|
|
||||||
{ NULL, NULL, NULL },
|
{ NULL, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
Py_InitModule("snd", s_methods);
|
Py_InitModule("snd", s_methods);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ void CPythonSystem::ChangeSystem()
|
|||||||
else
|
else
|
||||||
CScreen::SetShadowFlag(false);
|
CScreen::SetShadowFlag(false);
|
||||||
*/
|
*/
|
||||||
CSoundManager& rkSndMgr = CSoundManager::Instance();
|
SoundEngine& rkSndMgr = SoundEngine::Instance();
|
||||||
/*
|
/*
|
||||||
float fMusicVolume;
|
float fMusicVolume;
|
||||||
if (0 == m_Config.music_volume)
|
if (0 == m_Config.music_volume)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#include "eterPythonLib/StdAfx.h"
|
#include "eterPythonLib/StdAfx.h"
|
||||||
#include "gameLib/StdAfx.h"
|
#include "gameLib/StdAfx.h"
|
||||||
#include "scriptLib/StdAfx.h"
|
#include "scriptLib/StdAfx.h"
|
||||||
#include "milesLib/StdAfx.h"
|
#include "AudioLib/StdAfx.h"
|
||||||
#include "EffectLib/StdAfx.h"
|
#include "EffectLib/StdAfx.h"
|
||||||
#include "PRTerrainLib/StdAfx.h"
|
#include "PRTerrainLib/StdAfx.h"
|
||||||
#include "SpeedTreeLib/StdAfx.h"
|
#include "SpeedTreeLib/StdAfx.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user