Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for Game-Specific Menu Music #11241

Merged
merged 10 commits into from Nov 22, 2021
2 changes: 1 addition & 1 deletion builtin/mainmenu/dlg_create_world.lua
Expand Up @@ -393,7 +393,7 @@ local function create_world_buttonhandler(this, fields)
core.settings:set("menu_last_game",pkgmgr.games[gameindex].id)
if this.data.update_worldlist_filter then
menudata.worldlist:set_filtercriteria(pkgmgr.games[gameindex].id)
mm_texture.update("singleplayer", pkgmgr.games[gameindex].id)
mm_game_theme.update("singleplayer", pkgmgr.games[gameindex].id)
end
menudata.worldlist:refresh()
core.settings:set("mainmenu_last_selected_world",
Expand Down
98 changes: 58 additions & 40 deletions builtin/mainmenu/textures.lua → builtin/mainmenu/game_theme.lua
Expand Up @@ -16,109 +16,115 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


mm_texture = {}
mm_game_theme = {}

--------------------------------------------------------------------------------
function mm_texture.init()
mm_texture.defaulttexturedir = core.get_texturepath() .. DIR_DELIM .. "base" ..
function mm_game_theme.init()
mm_game_theme.defaulttexturedir = core.get_texturepath() .. DIR_DELIM .. "base" ..
DIR_DELIM .. "pack" .. DIR_DELIM
mm_texture.basetexturedir = mm_texture.defaulttexturedir
mm_game_theme.basetexturedir = mm_game_theme.defaulttexturedir

mm_texture.texturepack = core.settings:get("texture_path")
mm_game_theme.texturepack = core.settings:get("texture_path")

mm_texture.gameid = nil
mm_game_theme.gameid = nil

mm_game_theme.music_handle = nil
end

--------------------------------------------------------------------------------
function mm_texture.update(tab,gamedetails)
function mm_game_theme.update(tab,gamedetails)
if tab ~= "singleplayer" then
mm_texture.reset()
mm_game_theme.reset()
return
end

if gamedetails == nil then
return
end

mm_texture.update_game(gamedetails)
mm_game_theme.update_game(gamedetails)
end

--------------------------------------------------------------------------------
function mm_texture.reset()
mm_texture.gameid = nil
function mm_game_theme.reset()
mm_game_theme.gameid = nil
local have_bg = false
local have_overlay = mm_texture.set_generic("overlay")
local have_overlay = mm_game_theme.set_generic("overlay")

if not have_overlay then
have_bg = mm_texture.set_generic("background")
have_bg = mm_game_theme.set_generic("background")
end

mm_texture.clear("header")
mm_texture.clear("footer")
mm_game_theme.clear("header")
mm_game_theme.clear("footer")
core.set_clouds(false)

mm_texture.set_generic("footer")
mm_texture.set_generic("header")
mm_game_theme.set_generic("footer")
mm_game_theme.set_generic("header")

if not have_bg then
if core.settings:get_bool("menu_clouds") then
core.set_clouds(true)
else
mm_texture.set_dirt_bg()
mm_game_theme.set_dirt_bg()
end
end

if mm_game_theme.music_handle ~= nil then
core.sound_stop(mm_game_theme.music_handle)
end
end

--------------------------------------------------------------------------------
function mm_texture.update_game(gamedetails)
if mm_texture.gameid == gamedetails.id then
function mm_game_theme.update_game(gamedetails)
if mm_game_theme.gameid == gamedetails.id then
return
end

local have_bg = false
local have_overlay = mm_texture.set_game("overlay",gamedetails)
local have_overlay = mm_game_theme.set_game("overlay",gamedetails)

if not have_overlay then
have_bg = mm_texture.set_game("background",gamedetails)
have_bg = mm_game_theme.set_game("background",gamedetails)
end

mm_texture.clear("header")
mm_texture.clear("footer")
mm_game_theme.clear("header")
mm_game_theme.clear("footer")
core.set_clouds(false)

if not have_bg then

if core.settings:get_bool("menu_clouds") then
core.set_clouds(true)
else
mm_texture.set_dirt_bg()
mm_game_theme.set_dirt_bg()
end
end

mm_texture.set_game("footer",gamedetails)
mm_texture.set_game("header",gamedetails)
mm_game_theme.set_game("footer",gamedetails)
mm_game_theme.set_game("header",gamedetails)

mm_texture.gameid = gamedetails.id
mm_game_theme.gameid = gamedetails.id
end

--------------------------------------------------------------------------------
function mm_texture.clear(identifier)
function mm_game_theme.clear(identifier)
core.set_background(identifier,"")
end

--------------------------------------------------------------------------------
function mm_texture.set_generic(identifier)
function mm_game_theme.set_generic(identifier)
--try texture pack first
if mm_texture.texturepack ~= nil then
local path = mm_texture.texturepack .. DIR_DELIM .."menu_" ..
if mm_game_theme.texturepack ~= nil then
local path = mm_game_theme.texturepack .. DIR_DELIM .."menu_" ..
identifier .. ".png"
if core.set_background(identifier,path) then
return true
end
end

if mm_texture.defaulttexturedir ~= nil then
local path = mm_texture.defaulttexturedir .. DIR_DELIM .."menu_" ..
if mm_game_theme.defaulttexturedir ~= nil then
local path = mm_game_theme.defaulttexturedir .. DIR_DELIM .."menu_" ..
identifier .. ".png"
if core.set_background(identifier,path) then
return true
Expand All @@ -129,14 +135,16 @@ function mm_texture.set_generic(identifier)
end

--------------------------------------------------------------------------------
function mm_texture.set_game(identifier, gamedetails)
function mm_game_theme.set_game(identifier, gamedetails)

if gamedetails == nil then
return false
end

if mm_texture.texturepack ~= nil then
local path = mm_texture.texturepack .. DIR_DELIM ..
mm_game_theme.set_music(gamedetails)

if mm_game_theme.texturepack ~= nil then
local path = mm_game_theme.texturepack .. DIR_DELIM ..
gamedetails.id .. "_menu_" .. identifier .. ".png"
if core.set_background(identifier, path) then
return true
Expand Down Expand Up @@ -171,9 +179,10 @@ function mm_texture.set_game(identifier, gamedetails)
return false
end

function mm_texture.set_dirt_bg()
if mm_texture.texturepack ~= nil then
local path = mm_texture.texturepack .. DIR_DELIM .."default_dirt.png"
--------------------------------------------------------------------------------
function mm_game_theme.set_dirt_bg()
if mm_game_theme.texturepack ~= nil then
local path = mm_game_theme.texturepack .. DIR_DELIM .."default_dirt.png"
if core.set_background("background", path, true, 128) then
return true
end
Expand All @@ -183,3 +192,12 @@ function mm_texture.set_dirt_bg()
local minimalpath = defaulttexturedir .. "menu_bg.png"
core.set_background("background", minimalpath, true, 128)
end

--------------------------------------------------------------------------------
function mm_game_theme.set_music(gamedetails)
if mm_game_theme.music_handle ~= nil then
core.sound_stop(mm_game_theme.music_handle)
end
local music_path = gamedetails.path .. DIR_DELIM .. "menu" .. DIR_DELIM .. "theme"
mm_game_theme.music_handle = core.sound_play(music_path, true)
end
8 changes: 3 additions & 5 deletions builtin/mainmenu/init.lua
Expand Up @@ -35,7 +35,7 @@ dofile(menupath .. DIR_DELIM .. "async_event.lua")
dofile(menupath .. DIR_DELIM .. "common.lua")
dofile(menupath .. DIR_DELIM .. "pkgmgr.lua")
dofile(menupath .. DIR_DELIM .. "serverlistmgr.lua")
dofile(menupath .. DIR_DELIM .. "textures.lua")
dofile(menupath .. DIR_DELIM .. "game_theme.lua")

dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")
dofile(menupath .. DIR_DELIM .. "dlg_settings_advanced.lua")
Expand Down Expand Up @@ -87,7 +87,7 @@ local function init_globals()
core.settings:set("menu_last_game", default_game)
end

mm_texture.init()
mm_game_theme.init()

-- Create main tabview
local tv_main = tabview_create("maintab", {x = 12, y = 5.4}, {x = 0, y = 0})
Expand All @@ -113,16 +113,14 @@ local function init_globals()
if tv_main.current_tab == "local" then
local game = pkgmgr.find_by_gameid(core.settings:get("menu_last_game"))
if game == nil then
mm_texture.reset()
mm_game_theme.reset()
end
end

ui.set_default("maintab")
tv_main:show()

ui.update()

core.sound_play("main_menu", true)
end

init_globals()
12 changes: 6 additions & 6 deletions builtin/mainmenu/tab_local.lua
Expand Up @@ -54,7 +54,7 @@ if enable_gamebar then
for key,value in pairs(fields) do
for j=1,#pkgmgr.games,1 do
if ("game_btnbar_" .. pkgmgr.games[j].id == key) then
mm_texture.update("singleplayer", pkgmgr.games[j])
mm_game_theme.update("singleplayer", pkgmgr.games[j])
core.set_topleft_text(pkgmgr.games[j].name)
core.settings:set("menu_last_game",pkgmgr.games[j].id)
menudata.worldlist:set_filtercriteria(pkgmgr.games[j].id)
Expand Down Expand Up @@ -323,7 +323,7 @@ local function main_button_handler(this, fields, name, tabdata)
create_world_dlg:set_parent(this)
this:hide()
create_world_dlg:show()
mm_texture.update("singleplayer", current_game())
mm_game_theme.update("singleplayer", current_game())
return true
end

Expand All @@ -340,7 +340,7 @@ local function main_button_handler(this, fields, name, tabdata)
delete_world_dlg:set_parent(this)
this:hide()
delete_world_dlg:show()
mm_texture.update("singleplayer",current_game())
mm_game_theme.update("singleplayer",current_game())
end
end

Expand All @@ -358,7 +358,7 @@ local function main_button_handler(this, fields, name, tabdata)
configdialog:set_parent(this)
this:hide()
configdialog:show()
mm_texture.update("singleplayer",current_game())
mm_game_theme.update("singleplayer",current_game())
end
end

Expand All @@ -375,7 +375,7 @@ if enable_gamebar then
if game then
menudata.worldlist:set_filtercriteria(game.id)
core.set_topleft_text(game.name)
mm_texture.update("singleplayer",game)
mm_game_theme.update("singleplayer",game)
end

singleplayer_refresh_gamebar()
Expand All @@ -387,7 +387,7 @@ if enable_gamebar then
gamebar:hide()
end
core.set_topleft_text("")
mm_texture.update(new_tab,nil)
mm_game_theme.update(new_tab,nil)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion builtin/mainmenu/tab_settings.lua
Expand Up @@ -247,7 +247,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
adv_settings_dlg:set_parent(this)
this:hide()
adv_settings_dlg:show()
--mm_texture.update("singleplayer", current_game())
--mm_game_theme.update("singleplayer", current_game())
return true
end
if fields["cb_smooth_lighting"] then
Expand Down
10 changes: 10 additions & 0 deletions doc/lua_api.txt
Expand Up @@ -113,8 +113,16 @@ If you want to specify multiple images for one identifier, add additional
images named like `$identifier.$n.png`, with an ascending number $n starting
with 1, and a random image will be chosen from the provided ones.

Menu music
-----------

Games can provide custom main menu music. They are put inside a `menu`
directory inside the game directory.

The music files are named `theme.ogg`.
If you want to specify multiple music files for one game, add additional
images named like `theme.$n.ogg`, with an ascending number $n starting
with 1 (max 10), and a random music file will be chosen from the provided ones.

Mods
====
Expand Down Expand Up @@ -5608,6 +5616,8 @@ Sounds
player actions (e.g. door closing).
* `minetest.sound_stop(handle)`
* `handle` is a handle returned by `minetest.sound_play`
* `minetest.sound_stop_all()`
Stops all currently playing non-ephermeral sounds.
* `minetest.sound_fade(handle, step, gain)`
* `handle` is a handle returned by `minetest.sound_play`
* `step` determines how fast a sound will fade.
Expand Down
26 changes: 16 additions & 10 deletions src/gui/guiEngine.cpp
Expand Up @@ -104,16 +104,22 @@ void MenuMusicFetcher::fetchSounds(const std::string &name,
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");
std::vector<fs::DirListNode> list;
// Reusable local function
auto add_paths = [&dst_paths](const std::string name, const std::string base = "") {
dst_paths.insert(base + name + ".ogg");
for (int i = 0; i < 10; i++)
dst_paths.insert(base + name + "." + itos(i) + ".ogg");
};
// Allow full paths
if (name.find(DIR_DELIM_CHAR) != std::string::npos) {
add_paths(name);
} else {
std::string share_prefix = porting::path_share + DIR_DELIM;
add_paths(name, share_prefix + "sounds" + DIR_DELIM);
std::string user_prefix = porting::path_user + DIR_DELIM;
add_paths(name, user_prefix + "sounds" + DIR_DELIM);
}
}

/******************************************************************************/
Expand Down