diff --git a/src/engine/client.h b/src/engine/client.h index eb8b25d20..87a991eb1 100644 --- a/src/engine/client.h +++ b/src/engine/client.h @@ -101,7 +101,8 @@ public: virtual void Restart() = 0; virtual void Quit() = 0; - virtual const char *DemoPlayer_Play(const char *pFilename, int StorageType, bool DemoRender) = 0; + virtual const char *DemoPlayer_Play(const char *pFilename, int StorageType) = 0; + virtual const char *DemoPlayer_Render(const char *pFilename, int StorageType, const char *pVideoName) = 0; virtual void DemoRecorder_Start(const char *pFilename, bool WithTimestamp, int Recorder) = 0; virtual void DemoRecorder_HandleAutoStart() = 0; virtual void DemoRecorder_Stop(int Recorder, bool RemoveFile = false) = 0; diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 860ac7e28..5c548201d 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -3317,7 +3317,24 @@ void CClient::Con_StartVideo(IConsole::IResult *pResult, void *pUserData) if (!IVideo::Current()) { - new CVideo((CGraphics_Threaded*)pSelf->m_pGraphics, pSelf->Storage(), pSelf->m_pConsole, pSelf->Graphics()->ScreenWidth(), pSelf->Graphics()->ScreenHeight()); + new CVideo((CGraphics_Threaded*)pSelf->m_pGraphics, pSelf->Storage(), pSelf->m_pConsole, pSelf->Graphics()->ScreenWidth(), pSelf->Graphics()->ScreenHeight(), NULL); + IVideo::Current()->start(); + } + else + pSelf->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "videorecorder", "Videorecorder already running."); +} + +void CClient::StartVideo(IConsole::IResult *pResult, void *pUserData, const char *pVideoName) +{ + CClient *pSelf = (CClient *)pUserData; + + if (pSelf->State() != IClient::STATE_DEMOPLAYBACK) + pSelf->m_pConsole->Print(IConsole::OUTPUT_LEVEL_STANDARD, "videorecorder", "Can not start videorecorder outside of demoplayer."); + + //pSelf->m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "demo_render", pVideoName); + if (!IVideo::Current()) + { + new CVideo((CGraphics_Threaded*)pSelf->m_pGraphics, pSelf->Storage(), pSelf->m_pConsole, pSelf->Graphics()->ScreenWidth(), pSelf->Graphics()->ScreenHeight(), pVideoName); IVideo::Current()->start(); } else @@ -3459,7 +3476,7 @@ void CClient::DemoSlice(const char *pDstPath, CLIENTFUNC_FILTER pfnFilter, void } } -const char *CClient::DemoPlayer_Play(const char *pFilename, int StorageType, bool DemoRender) +const char *CClient::DemoPlayer_Play(const char *pFilename, int StorageType) { int Crc; const char *pError; @@ -3505,23 +3522,24 @@ const char *CClient::DemoPlayer_Play(const char *pFilename, int StorageType, boo // enter demo playback state SetState(IClient::STATE_DEMOPLAYBACK); - m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "demo_render", DemoRender?"true":"false"); - if (DemoRender) - { - m_DemoRender = true; - this->CClient::Con_StartVideo(NULL, this); - } - if(m_DemoPlayer.Play() == 0) + m_DemoPlayer.Play(); //m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "demo_recorder", "demo eof"); GameClient()->OnEnterGame(); return 0; } +const char *CClient::DemoPlayer_Render(const char *pFilename, int StorageType, const char *pVideoName) +{ + DemoPlayer_Play(pFilename, StorageType); + //m_pConsole->Print(IConsole::OUTPUT_LEVEL_DEBUG, "demo_recorder", pVideoName); + this->CClient::StartVideo(NULL, this, pVideoName); +} + void CClient::Con_Play(IConsole::IResult *pResult, void *pUserData) { CClient *pSelf = (CClient *)pUserData; - pSelf->DemoPlayer_Play(pResult->GetString(0), IStorage::TYPE_ALL, false); + pSelf->DemoPlayer_Play(pResult->GetString(0), IStorage::TYPE_ALL); } void CClient::Con_DemoPlay(IConsole::IResult *pResult, void *pUserData) diff --git a/src/engine/client/client.h b/src/engine/client/client.h index f7ba1d6c0..d77cedbcd 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -287,7 +287,6 @@ public: virtual bool DummyConnecting(); int m_DummyConnected; int m_LastDummyConnectTime; - bool m_DemoRender = false; virtual void GetServerInfo(CServerInfo *pServerInfo); void ServerInfoRequest(); @@ -362,6 +361,7 @@ public: static void Con_Screenshot(IConsole::IResult *pResult, void *pUserData); #if defined(CONF_VIDEORECORDER) + static void StartVideo(IConsole::IResult *pResult, void *pUserData, const char *pVideName); static void Con_StartVideo(IConsole::IResult *pResult, void *pUserData); static void Con_StopVideo(IConsole::IResult *pResult, void *pUserData); #endif @@ -391,7 +391,8 @@ public: void RegisterCommands(); - const char *DemoPlayer_Play(const char *pFilename, int StorageType, bool DemoRender); + const char *DemoPlayer_Play(const char *pFilename, int StorageType); + const char *DemoPlayer_Render(const char *pFilename, int StorageType, const char *pVideoName); void DemoRecorder_Start(const char *pFilename, bool WithTimestamp, int Recorder); void DemoRecorder_HandleAutoStart(); void DemoRecorder_StartReplayRecorder(); diff --git a/src/engine/client/video.cpp b/src/engine/client/video.cpp index fd7fd755b..e8a084e32 100644 --- a/src/engine/client/video.cpp +++ b/src/engine/client/video.cpp @@ -10,7 +10,7 @@ #define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */ -CVideo::CVideo(CGraphics_Threaded* pGraphics, IStorage* pStorage, IConsole *pConsole, int width, int height) : +CVideo::CVideo(CGraphics_Threaded* pGraphics, IStorage* pStorage, IConsole *pConsole, int width, int height, const char *name) : m_pGraphics(pGraphics), m_pStorage(pStorage), m_pConsole(pConsole), @@ -29,6 +29,7 @@ CVideo::CVideo(CGraphics_Threaded* pGraphics, IStorage* pStorage, IConsole *pCon m_Width = width; m_Height = height; + str_copy(m_Name, name, sizeof(m_Name)); m_FPS = g_Config.m_ClVideoRecorderFPS; @@ -60,8 +61,11 @@ void CVideo::start() { char aDate[20]; str_timestamp(aDate, sizeof(aDate)); - char aBuf[64]; - str_format(aBuf, sizeof(aBuf), "videos/%s.mp4", aDate); + char aBuf[256]; + if (strlen(m_Name) == 0) + str_format(aBuf, sizeof(aBuf), "videos/%s", m_Name); + else + str_format(aBuf, sizeof(aBuf), "videos/%s.mp4", aDate); char aWholePath[1024]; IOHANDLE File = m_pStorage->OpenFile(aBuf, IOFLAG_WRITE, IStorage::TYPE_SAVE, aWholePath, sizeof(aWholePath)); diff --git a/src/engine/client/video.h b/src/engine/client/video.h index d9697ce45..77f519ff8 100644 --- a/src/engine/client/video.h +++ b/src/engine/client/video.h @@ -52,7 +52,7 @@ typedef struct OutputStream { class CVideo : public IVideo { public: - CVideo(class CGraphics_Threaded* pGraphics, class IStorage* pStorage, class IConsole *pConsole, int width, int height); + CVideo(class CGraphics_Threaded* pGraphics, class IStorage* pStorage, class IConsole *pConsole, int width, int height, const char *name); ~CVideo(); virtual void start(); @@ -91,6 +91,7 @@ private: int m_Width; int m_Height; + char m_Name[256]; int m_FPS; diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 604fd7026..30db32117 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -1114,6 +1114,12 @@ int CMenus::Render() pExtraText = ""; ExtraAlign = -1; } + else if(m_Popup == POPUP_RENDER_DEMO) + { + pTitle = Localize("Render demo"); + pExtraText = ""; + ExtraAlign = -1; + } else if(m_Popup == POPUP_REMOVE_FRIEND) { pTitle = Localize("Remove friend"); @@ -1525,6 +1531,63 @@ int CMenus::Render() static float Offset = 0.0f; DoEditBox(&Offset, &TextBox, m_aCurrentDemoFile, sizeof(m_aCurrentDemoFile), 12.0f, &Offset); } + else if(m_Popup == POPUP_RENDER_DEMO) + { + CUIRect Label, TextBox, Ok, Abort; + + Box.HSplitBottom(20.f, &Box, &Part); +#if defined(__ANDROID__) + Box.HSplitBottom(60.f, &Box, &Part); +#else + Box.HSplitBottom(24.f, &Box, &Part); +#endif + Part.VMargin(80.0f, &Part); + + Part.VSplitMid(&Abort, &Ok); + + Ok.VMargin(20.0f, &Ok); + Abort.VMargin(20.0f, &Abort); + + static int s_ButtonAbort = 0; + if(DoButton_Menu(&s_ButtonAbort, Localize("Abort"), 0, &Abort) || m_EscapePressed) + m_Popup = POPUP_NONE; + + static int s_ButtonOk = 0; + if(DoButton_Menu(&s_ButtonOk, Localize("Ok"), 0, &Ok) || m_EnterPressed) + { + m_Popup = POPUP_NONE; + // name video + if(m_DemolistSelectedIndex >= 0 && !m_DemolistSelectedIsDir) + { + char aBufOld[512]; + str_format(aBufOld, sizeof(aBufOld), "%s/%s", m_aCurrentDemoFolder, m_lDemos[m_DemolistSelectedIndex].m_aFilename); + int Length = str_length(m_aCurrentDemoFile); + char aBufNew[512]; + if(Length <= 3 || m_aCurrentDemoFile[Length-4] != '.' || str_comp_nocase(m_aCurrentDemoFile+Length-3, "mp4")) + str_format(aBufNew, sizeof(aBufNew), "%s.mp4", m_aCurrentDemoFile); + else + str_format(aBufNew, sizeof(aBufNew), "%s", m_aCurrentDemoFile); + const char *pError = Client()->DemoPlayer_Render(aBufOld, m_lDemos[m_DemolistSelectedIndex].m_StorageType, aBufNew); + if(pError) + PopupMessage(Localize("Error"), str_comp(pError, "error loading demo") ? pError : Localize("Error loading demo"), Localize("Ok")); + } + } + + Box.HSplitBottom(60.f, &Box, &Part); +#if defined(__ANDROID__) + Box.HSplitBottom(60.f, &Box, &Part); +#else + Box.HSplitBottom(24.f, &Box, &Part); +#endif + + Part.VSplitLeft(60.0f, 0, &Label); + Label.VSplitLeft(120.0f, 0, &TextBox); + TextBox.VSplitLeft(20.0f, 0, &TextBox); + TextBox.VSplitRight(60.0f, &TextBox, 0); + UI()->DoLabel(&Label, Localize("Video name:"), 18.0f, -1); + static float Offset = 0.0f; + DoEditBox(&Offset, &TextBox, m_aCurrentDemoFile, sizeof(m_aCurrentDemoFile), 12.0f, &Offset); + } else if(m_Popup == POPUP_REMOVE_FRIEND) { CUIRect Yes, No; diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp index 2a6c25b05..fed5a7ad3 100644 --- a/src/game/client/components/menus_demo.cpp +++ b/src/game/client/components/menus_demo.cpp @@ -1245,7 +1245,7 @@ void CMenus::RenderDemoList(CUIRect MainView) { char aBuf[512]; str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_lDemos[m_DemolistSelectedIndex].m_aFilename); - const char *pError = Client()->DemoPlayer_Play(aBuf, m_lDemos[m_DemolistSelectedIndex].m_StorageType, false); + const char *pError = Client()->DemoPlayer_Play(aBuf, m_lDemos[m_DemolistSelectedIndex].m_StorageType); if(pError) PopupMessage(Localize("Error"), str_comp(pError, "error loading demo") ? pError : Localize("Error loading demo"), Localize("Ok")); else @@ -1285,14 +1285,13 @@ void CMenus::RenderDemoList(CUIRect MainView) static int s_RenderButton = 0; if(DoButton_Menu(&s_RenderButton, Localize("Render"), 0, &RenderRect)) { - char aBuf[512]; - str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_lDemos[m_DemolistSelectedIndex].m_aFilename); - const char *pError = Client()->DemoPlayer_Play(aBuf, m_lDemos[m_DemolistSelectedIndex].m_StorageType, true); - if(pError) - PopupMessage(Localize("Error"), str_comp(pError, "error loading demo") ? pError : Localize("Error loading demo"), Localize("Ok")); - else + if(m_DemolistSelectedIndex >= 0) { + //char aBuf[512]; + //str_format(aBuf, sizeof(aBuf), "%s/%s", m_aCurrentDemoFolder, m_lDemos[m_DemolistSelectedIndex].m_aFilename); UI()->SetActiveItem(0); + m_Popup = POPUP_RENDER_DEMO; + str_copy(m_aCurrentDemoFile, m_lDemos[m_DemolistSelectedIndex].m_aFilename, sizeof(m_aCurrentDemoFile)); return; } /*