From 4fb4efd8ed54a81ea545e51265f2acdd01654f21 Mon Sep 17 00:00:00 2001
From: PilzAdam <pilzadam@minetest.net>
Date: Sun, 28 Jul 2013 23:14:42 +0200
Subject: [PATCH] Play sounds/main_menu.ogg in menu

---
 builtin/mainmenu.lua |  1 +
 doc/menu_lua_api.txt |  4 ++++
 src/guiEngine.cpp    | 31 ++++++++++++++++++++++++++++-
 src/guiEngine.h      | 31 +++++++++++++++++++++++++++++
 src/guiLuaApi.cpp    | 46 +++++++++++++++++++++++++++++++++++++++++++
 src/guiLuaApi.h      |  4 ++++
 src/main.cpp         | 47 +-------------------------------------------
 7 files changed, 117 insertions(+), 47 deletions(-)

diff --git a/builtin/mainmenu.lua b/builtin/mainmenu.lua
index febf1984a..0bd2b13aa 100644
--- a/builtin/mainmenu.lua
+++ b/builtin/mainmenu.lua
@@ -1106,5 +1106,6 @@ tabbuilder.init()
 menubar.refresh()
 modstore.init()
 
+engine.sound_play("main_menu", true)
 
 update_menu()
diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt
index 337091a93..164d7876a 100644
--- a/doc/menu_lua_api.txt
+++ b/doc/menu_lua_api.txt
@@ -82,6 +82,10 @@ engine.download_file(url,target)
 ^ returns true/false
 engine.get_version()
 ^ returns current minetest version
+engine.sound_play(spec, looped) -> handle
+^ spec = SimpleSoundSpec (see lua-api.txt)
+^ looped = bool
+engine.sound_stop(handle)
 
 GUI:
 engine.update_formspec(formspec)
diff --git a/src/guiEngine.cpp b/src/guiEngine.cpp
index 4c5d0189d..b62c1a547 100644
--- a/src/guiEngine.cpp
+++ b/src/guiEngine.cpp
@@ -30,6 +30,8 @@ extern "C" {
 #include "main.h"
 #include "settings.h"
 #include "guiMainMenu.h"
+#include "sound.h"
+#include "sound_openal.h"
 
 #include "guiEngine.h"
 
@@ -84,6 +86,7 @@ GUIEngine::GUIEngine(	irr::IrrlichtDevice* dev,
 	m_menumanager(menumgr),
 	m_smgr(smgr),
 	m_data(data),
+	m_sound_manager(NULL),
 	m_formspecgui(0),
 	m_buttonhandler(0),
 	m_menu(0),
@@ -122,6 +125,14 @@ GUIEngine::GUIEngine(	irr::IrrlichtDevice* dev,
 		m_data->errormessage = "";
 	}
 
+	//create soundmanager
+	MenuMusicFetcher soundfetcher;
+#if USE_SOUND
+	m_sound_manager = createOpenALSoundManager(&soundfetcher);
+#endif
+	if(!m_sound_manager)
+		m_sound_manager = &dummySoundManager;
+
 	//create topleft header
 	core::rect<s32> rect(0, 0, 500, 40);
 	rect += v2s32(4, 0);
@@ -299,7 +310,12 @@ GUIEngine::~GUIEngine()
 {
 	video::IVideoDriver* driver = m_device->getVideoDriver();
 	assert(driver != 0);
-	
+
+	if(m_sound_manager != &dummySoundManager){
+		delete m_sound_manager;
+		m_sound_manager = NULL;
+	}
+
 	//TODO: clean up m_menu here
 
 	lua_close(m_engineluastack);
@@ -571,3 +587,16 @@ void GUIEngine::setTopleftText(std::string append) {
 
 	m_irr_toplefttext->setText(narrow_to_wide(toset).c_str());
 }
+
+/******************************************************************************/
+s32 GUIEngine::playSound(SimpleSoundSpec spec, bool looped)
+{
+	s32 handle = m_sound_manager->playSound(spec, looped);
+	return handle;
+}
+
+/******************************************************************************/
+void GUIEngine::stopSound(s32 handle)
+{
+	m_sound_manager->stopSound(handle);
+}
diff --git a/src/guiEngine.h b/src/guiEngine.h
index 2445ed847..2f96b0b1c 100644
--- a/src/guiEngine.h
+++ b/src/guiEngine.h
@@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "clouds.h"
 #include "guiLuaApi.h"
 #include "guiFormSpecMenu.h"
+#include "sound.h"
 
 /******************************************************************************/
 /* Typedefs and macros                                                        */
@@ -50,6 +51,7 @@ typedef enum {
 /******************************************************************************/
 class GUIEngine;
 struct MainMenuData;
+struct SimpleSoundSpec;
 
 /******************************************************************************/
 /* declarations                                                               */
@@ -80,6 +82,30 @@ class TextDestGuiEngine : public TextDest
 	GUIEngine* m_engine;
 };
 
+class MenuMusicFetcher: public OnDemandSoundFetcher
+{
+	std::set<std::string> m_fetched;
+public:
+
+	void fetchSounds(const std::string &name,
+			std::set<std::string> &dst_paths,
+			std::set<std::string> &dst_datas)
+	{
+		if(m_fetched.count(name))
+			return;
+		m_fetched.insert(name);
+		std::string base;
+		base = porting::path_share + DIR_DELIM + "sounds";
+		dst_paths.insert(base + DIR_DELIM + name + ".ogg");
+		int i;
+		for(i=0; i<10; i++)
+			dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
+		base = porting::path_user + DIR_DELIM + "sounds";
+		dst_paths.insert(base + DIR_DELIM + name + ".ogg");
+		for(i=0; i<10; i++)
+			dst_paths.insert(base + DIR_DELIM + name + "."+itos(i)+".ogg");
+		}
+};
 
 /** implementation of main menu based uppon formspecs */
 class GUIEngine {
@@ -106,6 +132,9 @@ class GUIEngine {
 	/** default destructor */
 	virtual ~GUIEngine();
 
+	s32 playSound(SimpleSoundSpec spec, bool looped);
+	void stopSound(s32 handle);
+
 protected:
 	/**
 	 * process field data recieved from formspec
@@ -143,6 +172,8 @@ class GUIEngine {
 	scene::ISceneManager*	m_smgr;
 	/** pointer to data beeing transfered back to main game handling */
 	MainMenuData*			m_data;
+	/** pointer to soundmanager*/
+	ISoundManager*			m_sound_manager;
 
 	/** representation of form source to be used in mainmenu formspec */
 	FormspecFormSource*		m_formspecgui;
diff --git a/src/guiLuaApi.cpp b/src/guiLuaApi.cpp
index b00bb5a84..485cab883 100644
--- a/src/guiLuaApi.cpp
+++ b/src/guiLuaApi.cpp
@@ -31,6 +31,7 @@ extern "C" {
 #include "settings.h"
 #include "filesys.h"
 #include "convert_json.h"
+#include "sound.h"
 
 
 #include "IFileArchive.h"
@@ -92,6 +93,8 @@ void guiLuaApi::initialize(lua_State* L,GUIEngine* engine)
 	retval &= API_FCT(download_file);
 	retval &= API_FCT(get_modstore_details);
 	retval &= API_FCT(get_modstore_list);
+	retval &= API_FCT(sound_play);
+	retval &= API_FCT(sound_stop);
 
 	if (!retval) {
 		//TODO show error
@@ -1050,6 +1053,49 @@ int guiLuaApi::l_get_version(lua_State *L) {
 	return 1;
 }
 
+/******************************************************************************/
+int guiLuaApi::l_sound_play(lua_State *L) {
+	GUIEngine* engine = get_engine(L);
+
+	SimpleSoundSpec spec;
+	if(lua_isnil(L, 1))
+	{
+	} else if(lua_istable(L, 1)){
+		lua_getfield(L, 1, "name");
+		if(lua_isstring(L, -1)){
+			size_t len = 0;
+			spec.name = lua_tolstring(L, -1, &len);
+		}
+		lua_pop(L, 1);
+
+		//luaL_checkfloat(L, 1, "gain", spec.gain);
+		lua_getfield(L, 1, "gain");
+		if(lua_isnumber(L, -1)){
+			spec.gain = lua_tonumber(L, -1);
+		}
+		lua_pop(L, 1);
+	} else if(lua_isstring(L, 1)){
+		spec.name = luaL_checkstring(L, 1);
+	}
+	bool looped = lua_toboolean(L, 2);
+
+	u32 handle = engine->playSound(spec, looped);
+
+	lua_pushinteger(L, handle);
+
+	return 1;
+}
+
+/******************************************************************************/
+int guiLuaApi::l_sound_stop(lua_State *L) {
+	GUIEngine* engine = get_engine(L);
+
+	u32 handle = luaL_checkinteger(L, 1);
+	engine->stopSound(handle);
+
+	return 1;
+}
+
 /******************************************************************************/
 int guiLuaApi::l_download_file(lua_State *L) {
 	GUIEngine* engine = get_engine(L);
diff --git a/src/guiLuaApi.h b/src/guiLuaApi.h
index e0157f4a0..11b94ba75 100644
--- a/src/guiLuaApi.h
+++ b/src/guiLuaApi.h
@@ -127,6 +127,10 @@ class guiLuaApi {
 
 	static int l_get_version(lua_State *L);
 
+	static int l_sound_play(lua_State *L);
+
+	static int l_sound_stop(lua_State *L);
+
 	//gui
 
 	static int l_show_keys_menu(lua_State *L);
diff --git a/src/main.cpp b/src/main.cpp
index 8ed164d1f..716da57c3 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -76,8 +76,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "subgame.h"
 #include "quicktune.h"
 #include "serverlist.h"
-#include "sound.h"
-#include "sound_openal.h"
 #include "guiEngine.h"
 
 /*
@@ -205,49 +203,6 @@ u32 getTime(TimePrecision prec) {
 }
 #endif
 
-//Client side main menu music fetcher
-#ifndef SERVER
-class MenuMusicFetcher: public OnDemandSoundFetcher
-{
-	std::set<std::string> m_fetched;
-public:
-
-	void fetchSounds(const std::string &name,
-			std::set<std::string> &dst_paths,
-			std::set<std::string> &dst_datas)
-	{
-		if(m_fetched.count(name))
-			return;
-		m_fetched.insert(name);
-		std::string base;
-		base = porting::path_share + DIR_DELIM + "sounds";
-		dst_paths.insert(base + DIR_DELIM + name + ".ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".0.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".1.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".2.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".3.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".4.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".5.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".6.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".7.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".8.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".9.ogg");
-		base = porting::path_user + DIR_DELIM + "sounds";
-		dst_paths.insert(base + DIR_DELIM + name + ".ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".0.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".1.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".2.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".3.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".4.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".5.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".6.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".7.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".8.ogg");
-		dst_paths.insert(base + DIR_DELIM + name + ".9.ogg");
-		}
-};
-#endif
-
 class StderrLogOutput: public ILogOutput
 {
 public:
@@ -1711,7 +1666,7 @@ int main(int argc, char *argv[])
 				// Continue to game
 				break;
 			}
-			
+
 			// Break out of menu-game loop to shut down cleanly
 			if(device->run() == false || kill == true) {
 				g_settings->updateConfigFile(configpath.c_str());
-- 
GitLab