From 55e161336ab668434b716408dbfac1566c777e20 Mon Sep 17 00:00:00 2001 From: Kyzentun Keeslala Date: Wed, 3 Feb 2016 13:05:23 -0700 Subject: [PATCH] Added lua bindings for playing sounds in SCREENMAN. Added input redirection functions to SCREENMAN for disabling non-lua screen input processing. Added OF_FALSE, OV_EOF, and OV_HOLE to error string list in RageSound for more understandable messages. Made sure RageSound doesn't delete null pointers. Updated changelog. --- Docs/Changelog_sm5.txt | 12 +++++++ Docs/Luadoc/Lua.xml | 8 +++++ Docs/Luadoc/LuaDocumentation.xml | 25 +++++++++++++ src/Font.cpp | 2 +- src/RageSound.cpp | 10 ++++-- src/RageSoundReader_Vorbisfile.cpp | 7 +++- src/ScreenManager.cpp | 56 +++++++++++++++++++++++++++++- src/ScreenManager.h | 11 ++++++ src/ScreenSelectMusic.cpp | 34 +++++++++++++++++- src/ScreenSelectMusic.h | 2 ++ 10 files changed, 161 insertions(+), 6 deletions(-) diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index 7ec3bd71c6..283da29a30 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -4,6 +4,18 @@ The StepMania 5 Changelog covers all post-sm-ssc changes. For a list of changes from StepMania 4 alpha 5 to sm-ssc v1.2.5, see Changelog_sm-ssc.txt. ________________________________________________________________________________ +2016/02/03 +---------- +* [ScreenManager] Added PlayInvalidSound, PlayStartSound, PlayCoinSound, + PlayCancelSound, and PlayScreenshotSound lua bindings. [kyzentun] + Added get_input_redirected and set_input_redirected to allow the theme to + disable the normal input functions. (Example: a custom lua menu on + Select Music. When the menu is up, the theme doesn't want the player's + input to move the music wheel.) This is in SCREENMAN so that it will work + on all screens. [kyzentun] +* [ScreenSelectMusic] Added CanOpenOptionsList lua binding. OpenOptionsList + will do nothing if CanOpenOptionsList returns false. [kyzentun] + 2016/01/18 ---------- * [Edit Mode] Added "Clear timing in region" to timing menu. [kyzentun] diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml index 4fd6aa5f36..660c376c16 100644 --- a/Docs/Luadoc/Lua.xml +++ b/Docs/Luadoc/Lua.xml @@ -1488,10 +1488,17 @@ + + + + + + + @@ -1529,6 +1536,7 @@ + diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml index b4f5ce277f..0522f84c28 100644 --- a/Docs/Luadoc/LuaDocumentation.xml +++ b/Docs/Luadoc/LuaDocumentation.xml @@ -4389,6 +4389,24 @@ save yourself some time, copy this for undocumented things: Gets the screen at the top of the screen stack. + + Returns whether the input for the player has been redirected away from the normal screen input function. Input that has been redirected is only sent to lua input callbacks. + + + Plays the invalid sound. + + + Plays the start sound. + + + Plays the coin sound. + + + Plays the cancel sound. + + + Plays the screenshot sound. + Reloads any loaded overlay screens. @@ -4401,6 +4419,10 @@ save yourself some time, copy this for undocumented things: Sets the next screen to s. + + Sets whether the input for the player has been redirected away from the normal screen input function. Input that has been redirected is only sent to lua input callbacks.
+ This can be useful when putting a custom menu on a screen, and you want to disable the built in actors while the menu is open. Then you handle input through an input callback until the player closes the menu. +
Broadcasts a system message. @@ -4482,6 +4504,9 @@ save yourself some time, copy this for undocumented things:
+ + Returns false if the options list is already open or the UseOptionsList metric is false. + Returns true if the player is going to the options screen. diff --git a/src/Font.cpp b/src/Font.cpp index 2d46908580..99610d8c4d 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -610,7 +610,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr { LuaHelpers::ReportScriptErrorFmt( "The font definition \"%s\" tries to assign line %i, " - "but the font is only %i characters high." + "but the font is only %i characters high. " "Line numbers start at 0.", ini.GetPath().c_str(), first_frame, num_frames_high); continue; diff --git a/src/RageSound.cpp b/src/RageSound.cpp index 81fafdcfe4..d3dd0c2a0e 100644 --- a/src/RageSound.cpp +++ b/src/RageSound.cpp @@ -86,7 +86,10 @@ RageSound &RageSound::operator=( const RageSound &cpy ) m_bPlaying = false; m_bDeleteWhenFinished = false; - delete m_pSource; + if(m_pSource != NULL) + { + delete m_pSource; + } if( cpy.m_pSource ) m_pSource = cpy.m_pSource->Copy(); else @@ -104,7 +107,10 @@ void RageSound::Unload() LockMut(m_Mutex); - delete m_pSource; + if(m_pSource != NULL) + { + delete m_pSource; + } m_pSource = NULL; m_sFilePath = ""; diff --git a/src/RageSoundReader_Vorbisfile.cpp b/src/RageSoundReader_Vorbisfile.cpp index 5d6fb69da4..2c403e84fe 100644 --- a/src/RageSoundReader_Vorbisfile.cpp +++ b/src/RageSoundReader_Vorbisfile.cpp @@ -46,6 +46,11 @@ static RString ov_ssprintf( int err, const char *fmt, ...) RString errstr; switch( err ) { + // OV_FALSE, OV_EOF, and OV_HOLE were added to this switch because + // OV_EOF cases were being reported as unknown. -Kyz + case OV_FALSE: errstr = "OV_FALSE"; break; + case OV_EOF: errstr = "OV_EOF"; break; + case OV_HOLE: errstr = "OV_HOLE"; break; /* XXX: In the case of OV_EREAD, can we snoop at errno? */ case OV_EREAD: errstr = "Read error"; break; case OV_EFAULT: errstr = "Internal error"; break; @@ -123,7 +128,7 @@ int RageSoundReader_Vorbisfile::SetPosition( int iFrame ) if(ret < 0) { /* Returns OV_EINVAL on EOF. */ - if( ret == OV_EINVAL ) + if( ret == OV_EINVAL || ret == OV_EOF) { eof = true; return 0; diff --git a/src/ScreenManager.cpp b/src/ScreenManager.cpp index f9e4555ae4..9df8a92115 100644 --- a/src/ScreenManager.cpp +++ b/src/ScreenManager.cpp @@ -72,6 +72,7 @@ #include "ScreenDimensions.h" #include "Foreach.h" #include "ActorUtil.h" +#include "InputEventPlus.h" ScreenManager* SCREENMAN = NULL; // global and accessible from anywhere in our program @@ -366,6 +367,24 @@ bool ScreenManager::IsStackedScreen( const Screen *pScreen ) const return false; } +bool ScreenManager::get_input_redirected(PlayerNumber pn) +{ + if(pn >= m_input_redirected.size()) + { + return false; + } + return m_input_redirected[pn]; +} + +void ScreenManager::set_input_redirected(PlayerNumber pn, bool redir) +{ + while(pn >= m_input_redirected.size()) + { + m_input_redirected.push_back(false); + } + m_input_redirected[pn]= redir; +} + /* Pop the top screen off the stack, sending SM_LoseFocus messages and * returning the message the popped screen wants sent to the new top * screen. Does not send SM_GainFocus. */ @@ -534,7 +553,10 @@ void ScreenManager::Input( const InputEventPlus &input ) if( g_ScreenStack.empty() ) return; - g_ScreenStack.back().m_pScreen->Input( input ); + if(!get_input_redirected(input.pn)) + { + g_ScreenStack.back().m_pScreen->Input( input ); + } g_ScreenStack.back().m_pScreen->PassInputToLua( input ); } @@ -945,6 +967,32 @@ public: //static int GetScreenStackSize( T* p, lua_State *L ) { lua_pushnumber( L, ScreenManagerUtil::g_ScreenStack.size() ); return 1; } static int ReloadOverlayScreens( T* p, lua_State *L ) { p->ReloadOverlayScreens(); COMMON_RETURN_SELF; } + static int get_input_redirected(T* p, lua_State* L) + { + PlayerNumber pn= Enum::Check(L, 1); + lua_pushboolean(L, p->get_input_redirected(pn)); + return 1; + } + static int set_input_redirected(T* p, lua_State* L) + { + PlayerNumber pn= Enum::Check(L, 1); + p->set_input_redirected(pn, BArg(2)); + COMMON_RETURN_SELF; + } + +#define SCRMAN_PLAY_SOUND(sound_name) \ + static int Play##sound_name(T* p, lua_State* L) \ + { \ + p->Play##sound_name(); \ + COMMON_RETURN_SELF; \ + } + SCRMAN_PLAY_SOUND(InvalidSound); + SCRMAN_PLAY_SOUND(StartSound); + SCRMAN_PLAY_SOUND(CoinSound); + SCRMAN_PLAY_SOUND(CancelSound); + SCRMAN_PLAY_SOUND(ScreenshotSound); +#undef SCRMAN_PLAY_SOUND + LunaScreenManager() { ADD_METHOD( SetNewScreen ); @@ -955,6 +1003,12 @@ public: ADD_METHOD( AddNewScreenToTop ); //ADD_METHOD( GetScreenStackSize ); ADD_METHOD( ReloadOverlayScreens ); + ADD_METHOD(PlayInvalidSound); + ADD_METHOD(PlayStartSound); + ADD_METHOD(PlayCoinSound); + ADD_METHOD(PlayCancelSound); + ADD_METHOD(PlayScreenshotSound); + ADD_GET_SET_METHODS(input_redirected); } }; diff --git a/src/ScreenManager.h b/src/ScreenManager.h index f43b000b66..7380629f69 100644 --- a/src/ScreenManager.h +++ b/src/ScreenManager.h @@ -3,6 +3,7 @@ #include "ScreenMessage.h" #include "RageSound.h" +#include "PlayerNumber.h" class Actor; class Screen; @@ -64,6 +65,9 @@ public: * @return true if it's on the stack while not on the bottom, or false otherwise. */ bool IsStackedScreen( const Screen *pScreen ) const; + bool get_input_redirected(PlayerNumber pn); + void set_input_redirected(PlayerNumber pn, bool redir); + // Lua void PushSelf( lua_State *L ); @@ -86,6 +90,13 @@ private: // It's "AfterInput" because the debug overlay carries out actions in Input. bool m_bReloadOverlayScreensAfterInput; + // m_input_redirected exists to allow the theme to prevent input being + // passed to the normal Screen::Input function, on a per-player basis. + // Input is still passed to lua callbacks, so it's intended for the case + // where someone has a custom menu on a screen and needs to disable normal + // input for navigating the custom menu to work. -Kyz + std::vector m_input_redirected; + Screen *MakeNewScreen( const RString &sName ); void LoadDelayedScreen(); bool ActivatePreparedScreenAndBackground( const RString &sScreenName ); diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index d98d2031ac..a69e841570 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -2000,6 +2000,23 @@ void ScreenSelectMusic::OnConfirmSongDeletion() m_pSongAwaitingDeletionConfirmation = NULL; } +bool ScreenSelectMusic::can_open_options_list(PlayerNumber pn) +{ + if(!USE_OPTIONS_LIST) + { + return false; + } + if(pn >= NUM_PLAYERS) + { + return false; + } + if(m_OptionsList[pn].IsOpened()) + { + return false; + } + return true; +} + // lua start #include "LuaBinding.h" @@ -2013,13 +2030,28 @@ public: p->GetMusicWheel()->PushSelf(L); return 1; } - static int OpenOptionsList( T* p, lua_State *L ) { PlayerNumber pn = Enum::Check(L, 1); p->OpenOptionsList(pn); COMMON_RETURN_SELF; } + static int OpenOptionsList( T* p, lua_State *L ) + { + PlayerNumber pn = Enum::Check(L, 1); + if(p->can_open_options_list(pn)) + { + p->OpenOptionsList(pn); + } + COMMON_RETURN_SELF; + } + static int CanOpenOptionsList( T* p, lua_State *L ) + { + PlayerNumber pn = Enum::Check(L, 1); + lua_pushboolean(L, p->can_open_options_list(pn)); + return 1; + } LunaScreenSelectMusic() { ADD_METHOD( GetGoToOptions ); ADD_METHOD( GetMusicWheel ); ADD_METHOD( OpenOptionsList ); + ADD_METHOD( CanOpenOptionsList ); } }; diff --git a/src/ScreenSelectMusic.h b/src/ScreenSelectMusic.h index 2dddba6e64..ead8112e99 100644 --- a/src/ScreenSelectMusic.h +++ b/src/ScreenSelectMusic.h @@ -50,6 +50,8 @@ public: void OpenOptionsList( PlayerNumber pn ); void OnConfirmSongDeletion(); + bool can_open_options_list(PlayerNumber pn); + // Lua virtual void PushSelf( lua_State *L );