Commit e4081e20 authored by nanahira's avatar nanahira

use miniaudio

parent ed32d849
......@@ -1934,7 +1934,7 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) {
return true;
break;
}
#ifdef YGOPRO_USE_IRRKLANG
#ifdef YGOPRO_USE_AUDIO
case CHECKBOX_ENABLE_MUSIC: {
if(!mainGame->chkEnableMusic->isChecked())
soundManager.StopBGM();
......@@ -2053,7 +2053,7 @@ bool ClientField::OnCommonEvent(const irr::SEvent& event) {
return true;
break;
}
#ifdef YGOPRO_USE_IRRKLANG
#ifdef YGOPRO_USE_AUDIO
case SCROLL_VOLUME: {
mainGame->gameConf.sound_volume = (double)mainGame->scrSoundVolume->getPos() / 100;
mainGame->gameConf.music_volume = (double)mainGame->scrMusicVolume->getPos() / 100;
......
......@@ -1563,7 +1563,7 @@ bool Game::LoadConfigFromFile(const char* file) {
gameConf.window_height = strtol(valbuf, nullptr, 10);
} else if(!std::strcmp(strbuf, "resize_popup_menu")) {
gameConf.resize_popup_menu = strtol(valbuf, nullptr, 10) > 0;
#ifdef YGOPRO_USE_IRRKLANG
#ifdef YGOPRO_USE_AUDIO
} else if(!std::strcmp(strbuf, "enable_sound")) {
gameConf.enable_sound = strtol(valbuf, nullptr, 10) > 0;
} else if(!std::strcmp(strbuf, "sound_volume")) {
......@@ -1804,7 +1804,7 @@ void Game::SaveConfig() {
fprintf(fp, "window_width = %d\n", gameConf.window_width);
fprintf(fp, "window_height = %d\n", gameConf.window_height);
fprintf(fp, "resize_popup_menu = %d\n", gameConf.resize_popup_menu ? 1 : 0);
#ifdef YGOPRO_USE_IRRKLANG
#ifdef YGOPRO_USE_AUDIO
fprintf(fp, "enable_sound = %d\n", (chkEnableSound->isChecked() ? 1 : 0));
fprintf(fp, "enable_music = %d\n", (chkEnableMusic->isChecked() ? 1 : 0));
fprintf(fp, "#Volume of sound and music, between 0 and 100\n");
......@@ -2035,7 +2035,7 @@ void Game::initUtils() {
FileSystem::MakeDir("textures/cover2");
FileSystem::MakeDir("textures/pscale");
//sound
#ifdef YGOPRO_USE_IRRKLANG
#ifdef YGOPRO_USE_AUDIO
FileSystem::MakeDir("sound");
FileSystem::MakeDir("sound/BGM");
FileSystem::MakeDir("sound/BGM/advantage");
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
project "cminiaudio"
kind "StaticLib"
files { "*.c", "*.h" }
filter "system:linux"
links { "dl", "pthread", "m" }
include "lzma/."
include "spmemvfs/."
if USE_AUDIO then
include "miniaudio/."
end
project "YGOPro"
kind "WindowedApp"
......@@ -7,13 +10,6 @@ project "YGOPro"
files { "*.cpp", "*.h", "CGUISkinSystem/*.cpp", "CGUISkinSystem/*.h", "CXMLRegistry/*.cpp", "CXMLRegistry/*.h" }
includedirs { "../ocgcore" }
links { "ocgcore", "clzma", "cspmemvfs", LUA_LIB_NAME, "sqlite3", "irrlicht", "freetype", "event" }
if BUILD_IKPMP3 then
links { "ikpmp3" }
end
if BUILD_IKPMP3 then
links { "ikpmp3" }
end
if BUILD_EVENT then
includedirs { "../event/include" }
......@@ -43,29 +39,15 @@ project "YGOPro"
libdirs { SQLITE_LIB_DIR }
end
if USE_IRRKLANG then
defines { "YGOPRO_USE_IRRKLANG" }
includedirs { IRRKLANG_INCLUDE_DIR }
if not IRRKLANG_PRO then
libdirs { IRRKLANG_LIB_DIR }
end
if USE_AUDIO then
defines { "YGOPRO_USE_AUDIO" }
links { "cminiaudio" }
end
filter "system:windows"
defines { "_IRR_WCHAR_FILESYSTEM" }
files "ygopro.rc"
libdirs { "$(DXSDK_DIR)Lib/x86" }
if USE_IRRKLANG then
links { "irrKlang" }
if IRRKLANG_PRO then
defines { "IRRKLANG_STATIC" }
filter { "not configurations:Debug" }
libdirs { IRRKLANG_PRO_RELEASE_LIB_DIR }
filter { "configurations:Debug" }
libdirs { IRRKLANG_PRO_DEBUG_LIB_DIR }
filter {}
end
end
links { "opengl32", "ws2_32", "winmm", "gdi32", "kernel32", "user32", "imm32", "Dnsapi" }
filter "not action:vs*"
buildoptions { "-std=c++14", "-fno-rtti" }
......@@ -78,13 +60,6 @@ project "YGOPro"
buildoptions { "--target=arm64-apple-macos12" }
linkoptions { "-arch arm64" }
end
if USE_IRRKLANG then
links { "irrklang" }
end
filter "system:linux"
linkoptions { "-static-libstdc++", "-static-libgcc" }
links { "GL", "X11", "Xxf86vm" }
if USE_IRRKLANG then
links { "IrrKlang" }
linkoptions { IRRKLANG_LINK_RPATH }
end
#include "sound_manager.h"
#include "myfilesystem.h"
#ifdef YGOPRO_USE_IRRKLANG
#include "../ikpmp3/ikpMP3.h"
#endif
namespace ygo {
SoundManager soundManager;
bool SoundManager::Init() {
#ifdef YGOPRO_USE_IRRKLANG
#ifdef YGOPRO_USE_AUDIO
bgm_scene = -1;
previous_bgm_scene = -1;
RefreshBGMList();
bgm_process = false;
rnd.reset((unsigned int)std::time(nullptr));
engineSound = irrklang::createIrrKlangDevice();
engineMusic = irrklang::createIrrKlangDevice();
if(!engineSound || !engineMusic) {
if(ma_engine_init(nullptr, &engineSound) || ma_engine_init(nullptr, &engineMusic)) {
return false;
} else {
irrklang::ikpMP3Init(engineMusic);
return true;
}
#endif // YGOPRO_USE_IRRKLANG
// TODO: Implement other sound engines
#endif // YGOPRO_USE_AUDIO
return false;
}
void SoundManager::RefreshBGMList() {
#ifdef YGOPRO_USE_IRRKLANG
#ifdef YGOPRO_USE_AUDIO
RefershBGMDir(L"", BGM_DUEL);
RefershBGMDir(L"duel", BGM_DUEL);
RefershBGMDir(L"menu", BGM_MENU);
......@@ -51,138 +44,142 @@ void SoundManager::RefershBGMDir(std::wstring path, int scene) {
});
}
void SoundManager::PlaySoundEffect(int sound) {
#ifdef YGOPRO_USE_IRRKLANG
if(!mainGame->chkEnableSound->isChecked())
return;
engineSound->setSoundVolume(mainGame->gameConf.sound_volume);
char soundName[32];
switch(sound) {
case SOUND_SUMMON: {
engineSound->play2D("./sound/summon.wav");
strcpy(soundName, "summon");
break;
}
case SOUND_SPECIAL_SUMMON: {
engineSound->play2D("./sound/specialsummon.wav");
strcpy(soundName, "specialsummon");
break;
}
case SOUND_ACTIVATE: {
engineSound->play2D("./sound/activate.wav");
strcpy(soundName, "activate");
break;
}
case SOUND_SET: {
engineSound->play2D("./sound/set.wav");
strcpy(soundName, "set");
break;
}
case SOUND_FILP: {
engineSound->play2D("./sound/flip.wav");
strcpy(soundName, "flip");
break;
}
case SOUND_REVEAL: {
engineSound->play2D("./sound/reveal.wav");
strcpy(soundName, "reveal");
break;
}
case SOUND_EQUIP: {
engineSound->play2D("./sound/equip.wav");
strcpy(soundName, "equip");
break;
}
case SOUND_DESTROYED: {
engineSound->play2D("./sound/destroyed.wav");
strcpy(soundName, "destroyed");
break;
}
case SOUND_BANISHED: {
engineSound->play2D("./sound/banished.wav");
strcpy(soundName, "banished");
break;
}
case SOUND_TOKEN: {
engineSound->play2D("./sound/token.wav");
strcpy(soundName, "token");
break;
}
case SOUND_NEGATE: {
engineSound->play2D("./sound/negate.wav");
strcpy(soundName, "negate");
break;
}
case SOUND_ATTACK: {
engineSound->play2D("./sound/attack.wav");
strcpy(soundName, "attack");
break;
}
case SOUND_DIRECT_ATTACK: {
engineSound->play2D("./sound/directattack.wav");
strcpy(soundName, "directattack");
break;
}
case SOUND_DRAW: {
engineSound->play2D("./sound/draw.wav");
strcpy(soundName, "draw");
break;
}
case SOUND_SHUFFLE: {
engineSound->play2D("./sound/shuffle.wav");
strcpy(soundName, "shuffle");
break;
}
case SOUND_DAMAGE: {
engineSound->play2D("./sound/damage.wav");
strcpy(soundName, "damage");
break;
}
case SOUND_RECOVER: {
engineSound->play2D("./sound/gainlp.wav");
strcpy(soundName, "recover");
break;
}
case SOUND_COUNTER_ADD: {
engineSound->play2D("./sound/addcounter.wav");
strcpy(soundName, "addcounter");
break;
}
case SOUND_COUNTER_REMOVE: {
engineSound->play2D("./sound/removecounter.wav");
strcpy(soundName, "removecounter");
break;
}
case SOUND_COIN: {
engineSound->play2D("./sound/coinflip.wav");
strcpy(soundName, "coin");
break;
}
case SOUND_DICE: {
engineSound->play2D("./sound/diceroll.wav");
strcpy(soundName, "dice");
break;
}
case SOUND_NEXT_TURN: {
engineSound->play2D("./sound/nextturn.wav");
strcpy(soundName, "nextturn");
break;
}
case SOUND_PHASE: {
engineSound->play2D("./sound/phase.wav");
strcpy(soundName, "phase");
break;
}
case SOUND_MENU: {
engineSound->play2D("./sound/menu.wav");
strcpy(soundName, "menu");
break;
}
case SOUND_BUTTON: {
engineSound->play2D("./sound/button.wav");
strcpy(soundName, "button");
break;
}
case SOUND_INFO: {
engineSound->play2D("./sound/info.wav");
strcpy(soundName, "info");
break;
}
case SOUND_QUESTION: {
engineSound->play2D("./sound/question.wav");
strcpy(soundName, "question");
break;
}
case SOUND_CARD_PICK: {
engineSound->play2D("./sound/cardpick.wav");
strcpy(soundName, "cardpick");
break;
}
case SOUND_CARD_DROP: {
engineSound->play2D("./sound/carddrop.wav");
strcpy(soundName, "carddrop");
break;
}
case SOUND_PLAYER_ENTER: {
engineSound->play2D("./sound/playerenter.wav");
strcpy(soundName, "playerenter");
break;
}
case SOUND_CHAT: {
engineSound->play2D("./sound/chatmessage.wav");
strcpy(soundName, "chat");
break;
}
default:
break;
}
char soundPath[40];
snprintf(soundPath, 40, "./sound/%s.wav", soundName);
#ifdef YGOPRO_USE_AUDIO
ma_engine_set_volume(&engineSound, mainGame->gameConf.sound_volume);
auto res = ma_engine_play_sound(&engineSound, soundPath, nullptr);
#endif
}
void SoundManager::PlayDialogSound(irr::gui::IGUIElement * element) {
......@@ -208,25 +205,39 @@ void SoundManager::PlayDialogSound(irr::gui::IGUIElement * element) {
PlaySoundEffect(SOUND_QUESTION);
}
}
bool SoundManager::IsCurrentlyPlaying(char* song) {
#ifdef YGOPRO_USE_AUDIO
return currentPlayingMusic[0] && strcmp(currentPlayingMusic, song) == 0 && ma_sound_is_playing(&soundBGM);
#endif
return false;
}
void SoundManager::PlayMusic(char* song, bool loop) {
#ifdef YGOPRO_USE_IRRKLANG
#ifdef YGOPRO_USE_AUDIO
if(!mainGame->chkEnableMusic->isChecked())
return;
if(!engineMusic->isCurrentlyPlaying(song)) {
engineMusic->stopAllSounds();
engineMusic->setSoundVolume(mainGame->gameConf.music_volume);
soundBGM = engineMusic->play2D(song, loop, false, true);
if(!IsCurrentlyPlaying(song)) {
StopBGM();
strcpy(currentPlayingMusic, song);
#ifdef _WIN32
wchar_t song_w[1024];
BufferIO::DecodeUTF8(song, song_w);
ma_sound_init_from_file_w(&engineMusic, song_w, MA_SOUND_FLAG_ASYNC | MA_SOUND_FLAG_STREAM, nullptr, nullptr, &soundBGM);
#else
ma_sound_init_from_file(&engineMusic, song, MA_SOUND_FLAG_ASYNC | MA_SOUND_FLAG_STREAM, nullptr, nullptr, &soundBGM);
#endif
ma_sound_set_looping(&soundBGM, loop);
ma_sound_start(&soundBGM);
}
#endif
}
void SoundManager::PlayBGM(int scene) {
#ifdef YGOPRO_USE_IRRKLANG
#ifdef YGOPRO_USE_AUDIO
if(!mainGame->chkEnableMusic->isChecked() || bgm_process)
return;
if(!mainGame->chkMusicMode->isChecked())
scene = BGM_ALL;
char BGMName[1024];
if (((scene != bgm_scene) && (bgm_scene != BGM_CUSTOM)) || ((scene != previous_bgm_scene) && (bgm_scene == BGM_CUSTOM)) || (soundBGM && soundBGM->isFinished())) {
if ((scene != bgm_scene) && (bgm_scene != BGM_CUSTOM) || (scene != previous_bgm_scene) && (bgm_scene == BGM_CUSTOM) || !IsCurrentlyPlaying(currentPlayingMusic)) {
int count = BGMList[scene].size();
if(count <= 0)
return;
......@@ -241,10 +252,8 @@ void SoundManager::PlayBGM(int scene) {
#endif
}
void SoundManager::PlayCustomBGM(char* BGMName) {
#ifdef YGOPRO_USE_IRRKLANG
if(!mainGame->chkEnableMusic->isChecked() || !mainGame->chkMusicMode->isChecked() || bgm_process)
return;
if(engineMusic->isCurrentlyPlaying(BGMName))
#ifdef YGOPRO_USE_AUDIO
if(!mainGame->chkEnableMusic->isChecked() || !mainGame->chkMusicMode->isChecked() || bgm_process || IsCurrentlyPlaying(BGMName))
return;
bgm_process = true;
int pscene = bgm_scene;
......@@ -256,31 +265,32 @@ void SoundManager::PlayCustomBGM(char* BGMName) {
#endif
}
void SoundManager::PlayCustomSound(char* SoundName) {
#ifdef YGOPRO_USE_IRRKLANG
#ifdef YGOPRO_USE_AUDIO
if(!mainGame->chkEnableSound->isChecked())
return;
engineSound->setSoundVolume(mainGame->gameConf.sound_volume);
engineSound->play2D(SoundName);
ma_engine_set_volume(&engineSound, mainGame->gameConf.sound_volume);
ma_engine_play_sound(&engineSound, SoundName, nullptr);
#endif
}
void SoundManager::StopBGM() {
#ifdef YGOPRO_USE_IRRKLANG
engineMusic->stopAllSounds();
#ifdef YGOPRO_USE_AUDIO
if(!currentPlayingMusic[0])
return;
memset(currentPlayingMusic, 0, sizeof(currentPlayingMusic));
ma_sound_uninit(&soundBGM);
#endif
}
void SoundManager::StopSound() {
#ifdef YGOPRO_USE_IRRKLANG
engineSound->stopAllSounds();
#endif
// TODO: stop all sounds
}
void SoundManager::SetSoundVolume(double volume) {
#ifdef YGOPRO_USE_IRRKLANG
engineSound->setSoundVolume(volume);
#ifdef YGOPRO_USE_AUDIO
ma_engine_set_volume(&engineSound, volume);
#endif
}
void SoundManager::SetMusicVolume(double volume) {
#ifdef YGOPRO_USE_IRRKLANG
engineMusic->setSoundVolume(volume);
#ifdef YGOPRO_USE_AUDIO
ma_engine_set_volume(&engineMusic, volume);
#endif
}
}
......@@ -3,8 +3,9 @@
#include "game.h"
#include "../ocgcore/mtrandom.h"
#ifdef YGOPRO_USE_IRRKLANG
#include <irrKlang.h>
#ifdef YGOPRO_USE_AUDIO
#define MINIAUDIO_IMPLEMENTATION
#include "miniaudio/miniaudio.h"
#endif
namespace ygo {
......@@ -16,10 +17,11 @@ private:
int previous_bgm_scene;
bool bgm_process;
mt19937 rnd;
#ifdef YGOPRO_USE_IRRKLANG
irrklang::ISoundEngine* engineSound;
irrklang::ISoundEngine* engineMusic;
irrklang::ISound* soundBGM;
#ifdef YGOPRO_USE_AUDIO
ma_engine engineSound;
ma_engine engineMusic;
ma_sound soundBGM;
char currentPlayingMusic[1024]{};
#endif
void RefershBGMDir(std::wstring path, int scene);
......@@ -28,6 +30,7 @@ public:
void RefreshBGMList();
void PlaySoundEffect(int sound);
void PlayDialogSound(irr::gui::IGUIElement * element);
bool IsCurrentlyPlaying(char* song);
void PlayMusic(char* song, bool loop);
void PlayBGM(int scene);
void PlayCustomBGM(char* BGMName);
......
......@@ -5,8 +5,6 @@ BUILD_EVENT = os.istarget("windows")
BUILD_FREETYPE = os.istarget("windows")
BUILD_SQLITE = os.istarget("windows")
BUILD_IRRLICHT = not os.istarget("macosx")
USE_IRRKLANG = true
IRRKLANG_PRO = false
LUA_LIB_NAME = "lua"
-- read settings from command line or environment variables
......@@ -38,11 +36,6 @@ newoption { trigger = "no-build-irrlicht", category = "YGOPro - irrlicht", descr
newoption { trigger = "irrlicht-include-dir", category = "YGOPro - irrlicht", description = "", value = "PATH" }
newoption { trigger = "irrlicht-lib-dir", category = "YGOPro - irrlicht", description = "", value = "PATH" }
newoption { trigger = "use-irrklang", category = "YGOPro - irrklang", description = "" }
newoption { trigger = "no-use-irrklang", category = "YGOPro - irrklang", description = "" }
newoption { trigger = "irrklang-include-dir", category = "YGOPro - irrklang", description = "", value = "PATH" }
newoption { trigger = "irrklang-lib-dir", category = "YGOPro - irrklang", description = "", value = "PATH" }
newoption { trigger = "irrklang-pro", category = "YGOPro - irrklang - pro", description = "" }
newoption { trigger = "no-irrklang-pro", category = "YGOPro - irrklang - pro", description = "" }
newoption { trigger = "irrklang-pro-release-lib-dir", category = "YGOPro - irrklang - pro", description = "", value = "PATH" }
......@@ -161,36 +154,7 @@ if not BUILD_IRRLICHT then
IRRLICHT_LIB_DIR = GetParam("irrlicht-lib-dir") or "/usr/local/lib"
end
if GetParam("use-irrklang") then
USE_IRRKLANG = true
elseif GetParam("no-use-irrklang") then
USE_IRRKLANG = false
end
if USE_IRRKLANG then
IRRKLANG_INCLUDE_DIR = GetParam("irrklang-include-dir") or "../irrklang/include"
if os.istarget("windows") then
IRRKLANG_LIB_DIR = "../irrklang/lib/Win32-visualStudio"
elseif os.istarget("linux") then
IRRKLANG_LIB_DIR = "../irrklang/bin/linux-gcc-64"
IRRKLANG_LINK_RPATH = "-Wl,-rpath=./lib/"
elseif os.istarget("macosx") then
IRRKLANG_LIB_DIR = "../irrklang/bin/macosx-gcc"
end
IRRKLANG_LIB_DIR = GetParam("irrklang-lib-dir") or IRRKLANG_LIB_DIR
end
if GetParam("irrklang-pro") and os.istarget("windows") then
IRRKLANG_PRO = true
elseif GetParam("no-irrklang-pro") then
IRRKLANG_PRO = false
end
if IRRKLANG_PRO then
-- irrklang pro can't use the pro lib to debug
IRRKLANG_PRO_RELEASE_LIB_DIR = GetParam("irrklang-pro-release-lib-dir") or "../irrklang/lib/Win32-vs2019"
IRRKLANG_PRO_DEBUG_LIB_DIR = GetParam("irrklang-pro-debug-lib-dir") or "../irrklang/lib/Win32-visualStudio-debug"
end
BUILD_IKPMP3 = USE_IRRKLANG
USE_AUDIO = not GetParam("no-audio")
if GetParam("winxp-support") and os.istarget("windows") then
WINXP_SUPPORT = true
......@@ -293,6 +257,6 @@ workspace "YGOPro"
if BUILD_SQLITE then
include "sqlite3"
end
if BUILD_IKPMP3 then
include "ikpmp3"
end
--if BUILD_IKPMP3 then
-- include "ikpmp3"
--end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment