diff --git a/data/languages/bosnian.txt b/data/languages/bosnian.txt index e871ac536..10fd1a820 100644 --- a/data/languages/bosnian.txt +++ b/data/languages/bosnian.txt @@ -513,6 +513,9 @@ Aspect ratio Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -699,6 +702,9 @@ Make collision Make external == +Max Screenshots +== + Max demos == diff --git a/data/languages/czech.txt b/data/languages/czech.txt index c2e28d272..4df483a4b 100644 --- a/data/languages/czech.txt +++ b/data/languages/czech.txt @@ -489,6 +489,9 @@ Aspect ratio Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -687,6 +690,9 @@ Make collision Make external == +Max Screenshots +== + Max demos == diff --git a/data/languages/dutch.txt b/data/languages/dutch.txt index 9e30566fd..e57db832d 100644 --- a/data/languages/dutch.txt +++ b/data/languages/dutch.txt @@ -936,6 +936,12 @@ ZO Automatically record demos == +Automatically take game over screenshot +== + +Max Screenshots +== + Max demos == diff --git a/data/languages/finnish.txt b/data/languages/finnish.txt index 9f1af60ce..044deaf3c 100644 --- a/data/languages/finnish.txt +++ b/data/languages/finnish.txt @@ -513,6 +513,9 @@ Aspect ratio Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -699,6 +702,9 @@ Make collision Make external == +Max Screenshots +== + Max demos == diff --git a/data/languages/french.txt b/data/languages/french.txt index 711a591af..24364c125 100644 --- a/data/languages/french.txt +++ b/data/languages/french.txt @@ -747,6 +747,9 @@ Aspect ratio Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -819,6 +822,9 @@ Left mouse button to move. Hold shift to move the texture. Left mouse to drag. Hold ctrl to be more precise. Hold shift to alter time point aswell. Right click to delete. == +Max Screenshots +== + Max demos == diff --git a/data/languages/german.txt b/data/languages/german.txt index c514592f9..f06d798f7 100644 --- a/data/languages/german.txt +++ b/data/languages/german.txt @@ -936,6 +936,12 @@ ZO Automatically record demos == +Automatically take game over screenshot +== + +Max Screenshots +== + Max demos == diff --git a/data/languages/italian.txt b/data/languages/italian.txt index 08a003d12..6ff7e07c1 100644 --- a/data/languages/italian.txt +++ b/data/languages/italian.txt @@ -483,6 +483,9 @@ Aspect ratio Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -684,6 +687,9 @@ Make collision Make external == +Max Screenshots +== + Max demos == diff --git a/data/languages/polish.txt b/data/languages/polish.txt index 0d1d169f0..85871f9ad 100644 --- a/data/languages/polish.txt +++ b/data/languages/polish.txt @@ -795,6 +795,9 @@ Aspect ratio Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -855,6 +858,9 @@ Load Load map == +Max Screenshots +== + Max demos == diff --git a/data/languages/portuguese.txt b/data/languages/portuguese.txt index e5a27a31e..c1f33229b 100644 --- a/data/languages/portuguese.txt +++ b/data/languages/portuguese.txt @@ -510,6 +510,9 @@ Aspect ratio Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -699,6 +702,9 @@ Make collision Make external == +Max Screenshots +== + Max demos == diff --git a/data/languages/russian.txt b/data/languages/russian.txt index 01e601c36..47bb9ac35 100644 --- a/data/languages/russian.txt +++ b/data/languages/russian.txt @@ -807,6 +807,9 @@ Aspect ratio Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -861,6 +864,9 @@ Left mouse to drag. Hold ctrl to be more precise. Hold shift to alter time point Load map == +Max Screenshots +== + Max demos == diff --git a/data/languages/serbian.txt b/data/languages/serbian.txt index 8f6c67425..0071e6873 100644 --- a/data/languages/serbian.txt +++ b/data/languages/serbian.txt @@ -513,6 +513,9 @@ Aspect ratio Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -699,6 +702,9 @@ Make collision Make external == +Max Screenshots +== + Max demos == diff --git a/data/languages/swedish.txt b/data/languages/swedish.txt index 9d5301e6e..71dcd9eaa 100644 --- a/data/languages/swedish.txt +++ b/data/languages/swedish.txt @@ -483,6 +483,9 @@ Aspect ratio Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -684,6 +687,9 @@ Make collision Make external == +Max Screenshots +== + Max demos == diff --git a/data/languages/ukrainian.txt b/data/languages/ukrainian.txt index a78edb57b..be8bea899 100644 --- a/data/languages/ukrainian.txt +++ b/data/languages/ukrainian.txt @@ -855,6 +855,9 @@ Alpha value of the envelope Automatically record demos == +Automatically take game over screenshot +== + Blue value of the envelope == @@ -891,6 +894,9 @@ Left mouse to drag. Hold ctrl to be more precise. Hold shift to alter time point Load map == +Max Screenshots +== + Max demos == diff --git a/src/engine/client.h b/src/engine/client.h index df69fbb54..ab1f05479 100644 --- a/src/engine/client.h +++ b/src/engine/client.h @@ -78,6 +78,7 @@ public: virtual const char *DemoPlayer_Play(const char *pFilename, int StorageType) = 0; virtual void DemoRecorder_Start(const char *pFilename, bool WithTimestamp) = 0; virtual void DemoRecorder_Stop() = 0; + virtual void AutoScreenshot_Start() = 0; // networking virtual void EnterGame() = 0; diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp index 82e79a855..a2d5a53ff 100644 --- a/src/engine/client/client.cpp +++ b/src/engine/client/client.cpp @@ -413,6 +413,7 @@ CClient::CClient() : m_DemoPlayer(&m_SnapshotDelta), m_DemoRecorder(&m_SnapshotD m_WindowMustRefocus = 0; m_SnapCrcErrors = 0; + m_AutoScreenshotRecycle = false; m_AckGameTick = -1; m_CurrentRecvTick = 0; @@ -1938,6 +1939,8 @@ void CClient::Run() } } + AutoScreenshot_Cleanup(); + // check conditions if(State() == IClient::STATE_QUITING) break; @@ -2023,10 +2026,33 @@ void CClient::Con_Ping(IConsole::IResult *pResult, void *pUserData) pSelf->m_PingStartTime = time_get(); } +void CClient::AutoScreenshot_Start() +{ + if(g_Config.m_ClAutoScreenshot) + { + Graphics()->TakeScreenshot("auto/autoscreen"); + m_AutoScreenshotRecycle = true; + } +} + +void CClient::AutoScreenshot_Cleanup() +{ + if(m_AutoScreenshotRecycle) + { + if(g_Config.m_ClAutoScreenshotMax) + { + // clean up auto taken screens + CFileCollection AutoScreens; + AutoScreens.Init(Storage(), "screenshots/auto", "autoscreen", ".png", g_Config.m_ClAutoScreenshotMax); + } + m_AutoScreenshotRecycle = false; + } +} + void CClient::Con_Screenshot(IConsole::IResult *pResult, void *pUserData) { CClient *pSelf = (CClient *)pUserData; - pSelf->Graphics()->TakeScreenshot(); + pSelf->Graphics()->TakeScreenshot(0); } void CClient::Con_Rcon(IConsole::IResult *pResult, void *pUserData) diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 8486e4814..a73850373 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -140,6 +140,7 @@ class CClient : public IClient, public CDemoPlayer::IListner NETADDR m_ServerAddress; int m_WindowMustRefocus; int m_SnapCrcErrors; + bool m_AutoScreenshotRecycle; int m_AckGameTick; int m_CurrentRecvTick; @@ -319,6 +320,9 @@ public: void DemoRecorder_HandleAutoStart(); void DemoRecorder_Stop(); + void AutoScreenshot_Start(); + void AutoScreenshot_Cleanup(); + virtual class CEngine *Engine() { return &m_Engine; } }; #endif diff --git a/src/engine/client/graphics.cpp b/src/engine/client/graphics.cpp index fb9949533..82248f058 100644 --- a/src/engine/client/graphics.cpp +++ b/src/engine/client/graphics.cpp @@ -873,8 +873,11 @@ int CGraphics_SDL::WindowOpen() } -void CGraphics_SDL::TakeScreenshot() +void CGraphics_SDL::TakeScreenshot(const char *pFilename) { + char aDate[20]; + str_timestamp(aDate, sizeof(aDate)); + str_format(m_aScreenshotName, sizeof(m_aScreenshotName), "screenshots/%s_%s.png", pFilename?pFilename:"screenshot", aDate); m_DoScreenshot = true; } @@ -882,12 +885,7 @@ void CGraphics_SDL::Swap() { if(m_DoScreenshot) { - char aFilename[128]; - char aDate[20]; - - str_timestamp(aDate, sizeof(aDate)); - str_format(aFilename, sizeof(aFilename), "screenshots/screenshot_%s.png", aDate); - ScreenshotDirect(aFilename); + ScreenshotDirect(m_aScreenshotName); m_DoScreenshot = false; } diff --git a/src/engine/client/graphics.h b/src/engine/client/graphics.h index 17e3a83fa..20be3504f 100644 --- a/src/engine/client/graphics.h +++ b/src/engine/client/graphics.h @@ -41,6 +41,7 @@ protected: float m_Rotation; int m_Drawing; bool m_DoScreenshot; + char m_aScreenshotName[128]; float m_ScreenX0; float m_ScreenY0; @@ -136,7 +137,7 @@ public: virtual int WindowActive(); virtual int WindowOpen(); - virtual void TakeScreenshot(); + virtual void TakeScreenshot(const char *pFilename); virtual void Swap(); virtual int GetVideoModes(CVideoMode *pModes, int MaxModes); diff --git a/src/engine/graphics.h b/src/engine/graphics.h index 305319f96..de99caac1 100644 --- a/src/engine/graphics.h +++ b/src/engine/graphics.h @@ -127,7 +127,7 @@ public: virtual void SetColorVertex(const CColorVertex *pArray, int Num) = 0; virtual void SetColor(float r, float g, float b, float a) = 0; - virtual void TakeScreenshot() = 0; + virtual void TakeScreenshot(const char *pFilename) = 0; virtual int GetVideoModes(CVideoMode *pModes, int MaxModes) = 0; virtual void Swap() = 0; diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index b34e733b0..ad84da0df 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -19,6 +19,8 @@ MACRO_CONFIG_INT(ClEditor, cl_editor, 0, 0, 1, CFGFLAG_CLIENT, "") MACRO_CONFIG_INT(ClAutoDemoRecord, cl_auto_demo_record, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Automatically record demos") MACRO_CONFIG_INT(ClAutoDemoMax, cl_auto_demo_max, 10, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Maximum number of automatically recorded demos (0 = no limit)") +MACRO_CONFIG_INT(ClAutoScreenshot, cl_auto_screenshot, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Automatically take game over screenshot") +MACRO_CONFIG_INT(ClAutoScreenshotMax, cl_auto_screenshot_max, 10, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Maximum number of automatically created screenshots (0 = no limit)") MACRO_CONFIG_INT(ClEventthread, cl_eventthread, 0, 0, 1, CFGFLAG_CLIENT, "Enables the usage of a thread to pump the events") diff --git a/src/engine/shared/storage.cpp b/src/engine/shared/storage.cpp index d19be8a87..ffbd3aff5 100644 --- a/src/engine/shared/storage.cpp +++ b/src/engine/shared/storage.cpp @@ -57,10 +57,12 @@ public: { char aPath[MAX_PATH_LENGTH]; fs_makedir(GetPath(TYPE_SAVE, "screenshots", aPath, sizeof(aPath))); + fs_makedir(GetPath(TYPE_SAVE, "screenshots/auto", aPath, sizeof(aPath))); fs_makedir(GetPath(TYPE_SAVE, "maps", aPath, sizeof(aPath))); fs_makedir(GetPath(TYPE_SAVE, "dumps", aPath, sizeof(aPath))); fs_makedir(GetPath(TYPE_SAVE, "downloadedmaps", aPath, sizeof(aPath))); fs_makedir(GetPath(TYPE_SAVE, "demos", aPath, sizeof(aPath))); + fs_makedir(GetPath(TYPE_SAVE, "demos/auto", aPath, sizeof(aPath))); } return m_NumPaths ? 0 : 1; diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 2145ccaba..5d9c1bde1 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -737,7 +737,7 @@ void CMenus::OnInit() // */ if(g_Config.m_ClShowWelcome) - m_Popup = POPUP_FIRST_LAUNCH; + m_Popup = POPUP_LANGUAGE; g_Config.m_ClShowWelcome = 0; Console()->Chain("add_favorite", ConchainServerbrowserUpdate, this); @@ -971,6 +971,23 @@ int CMenus::Render() static float Offset = 0.0f; DoEditBox(&g_Config.m_Password, &TextBox, g_Config.m_Password, sizeof(g_Config.m_Password), 12.0f, &Offset, true); } + else if(m_Popup == POPUP_LANGUAGE) + { + Box = Screen; + Box.VMargin(150.0f, &Box); + Box.HMargin(150.0f, &Box); + Box.HSplitTop(20.f, &Part, &Box); + Box.HSplitBottom(20.f, &Box, &Part); + Box.HSplitBottom(24.f, &Box, &Part); + Box.HSplitBottom(20.f, &Box, 0); + Box.VMargin(20.0f, &Box); + RenderLanguageSelection(Box); + Part.VMargin(120.0f, &Part); + + static int s_Button = 0; + if(DoButton_Menu(&s_Button, Localize("Ok"), 0, &Part) || m_EscapePressed || m_EnterPressed) + m_Popup = POPUP_FIRST_LAUNCH; + } else if(m_Popup == POPUP_DELETE_DEMO) { CUIRect Yes, No; diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index 8efb7969d..9ca21daed 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -95,6 +95,7 @@ class CMenus : public CComponent POPUP_MESSAGE, POPUP_DISCONNECTED, POPUP_PURE, + POPUP_LANGUAGE, POPUP_DELETE_DEMO, POPUP_PASSWORD, POPUP_QUIT, @@ -210,6 +211,7 @@ class CMenus : public CComponent static void ConchainServerbrowserUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData); // found in menus_settings.cpp + void RenderLanguageSelection(CUIRect MainView); void RenderSettingsGeneral(CUIRect MainView); void RenderSettingsPlayer(CUIRect MainView); void RenderSettingsControls(CUIRect MainView); diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index b12a0c8d5..f1b701ede 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -708,7 +708,7 @@ void LoadLanguageIndexfile(IStorage *pStorage, IConsole *pConsole, sorted_array< io_close(File); } -void CMenus::RenderSettingsGeneral(CUIRect MainView) +void CMenus::RenderLanguageSelection(CUIRect MainView) { static int s_LanguageList = 0; static int s_SelectedLanguage = 0; @@ -729,32 +729,7 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) int OldSelected = s_SelectedLanguage; - CUIRect List, Button, Label, Left; - MainView.HSplitBottom(10.0f, &MainView, 0); - MainView.HSplitBottom(70.0f, &MainView, &Left); - Left.VSplitMid(&Left, 0); - Left.HSplitTop(20.0f, &Button, &Left); - MainView.HSplitBottom(20.0f, &List, &MainView); - - // auto demo settings - { - if(DoButton_CheckBox(&g_Config.m_ClAutoDemoRecord, Localize("Automatically record demos"), g_Config.m_ClAutoDemoRecord, &Button)) - g_Config.m_ClAutoDemoRecord ^= 1; - - Left.HSplitTop(10.0f, 0, &Left); - Left.VSplitLeft(20.0f, 0, &Left); - Left.HSplitTop(20.0f, &Label, &Button); - Button.VSplitRight(20.0f, &Button, 0); - char aBuf[64]; - if(g_Config.m_ClAutoDemoMax) - str_format(aBuf, sizeof(aBuf), "%s: %i", Localize("Max demos"), g_Config.m_ClAutoDemoMax); - else - str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Max demos"), Localize("no limit")); - UI()->DoLabel(&Label, aBuf, 13.0f, -1); - g_Config.m_ClAutoDemoMax = static_cast(DoScrollbarH(&g_Config.m_ClAutoDemoMax, &Button, g_Config.m_ClAutoDemoMax/1000.0f)*1000.0f+0.1f); - } - - UiDoListboxStart(&s_LanguageList , &List, 24.0f, Localize("Language"), "", s_Languages.size(), 1, s_SelectedLanguage, s_ScrollValue); + UiDoListboxStart(&s_LanguageList , &MainView, 24.0f, Localize("Language"), "", s_Languages.size(), 1, s_SelectedLanguage, s_ScrollValue); for(sorted_array::range r = s_Languages.all(); !r.empty(); r.pop_front()) { @@ -773,6 +748,51 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) } } +void CMenus::RenderSettingsGeneral(CUIRect MainView) +{ + CUIRect List, Button, Label, Left, Right; + MainView.HSplitBottom(10.0f, &MainView, 0); + MainView.HSplitBottom(70.0f, &MainView, &Left); + Left.VSplitMid(&Left, &Right); + MainView.HSplitBottom(20.0f, &List, &MainView); + + // auto demo settings + { + Left.HSplitTop(20.0f, &Button, &Left); + if(DoButton_CheckBox(&g_Config.m_ClAutoDemoRecord, Localize("Automatically record demos"), g_Config.m_ClAutoDemoRecord, &Button)) + g_Config.m_ClAutoDemoRecord ^= 1; + + Right.HSplitTop(20.0f, &Button, &Right); + if(DoButton_CheckBox(&g_Config.m_ClAutoScreenshot, Localize("Automatically take game over screenshot"), g_Config.m_ClAutoScreenshot, &Button)) + g_Config.m_ClAutoScreenshot ^= 1; + + Left.HSplitTop(10.0f, 0, &Left); + Left.VSplitLeft(20.0f, 0, &Left); + Left.HSplitTop(20.0f, &Label, &Button); + Button.VSplitRight(20.0f, &Button, 0); + char aBuf[64]; + if(g_Config.m_ClAutoDemoMax) + str_format(aBuf, sizeof(aBuf), "%s: %i", Localize("Max demos"), g_Config.m_ClAutoDemoMax); + else + str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Max demos"), Localize("no limit")); + UI()->DoLabel(&Label, aBuf, 13.0f, -1); + g_Config.m_ClAutoDemoMax = static_cast(DoScrollbarH(&g_Config.m_ClAutoDemoMax, &Button, g_Config.m_ClAutoDemoMax/1000.0f)*1000.0f+0.1f); + + Right.HSplitTop(10.0f, 0, &Right); + Right.VSplitLeft(20.0f, 0, &Right); + Right.HSplitTop(20.0f, &Label, &Button); + Button.VSplitRight(20.0f, &Button, 0); + if(g_Config.m_ClAutoScreenshotMax) + str_format(aBuf, sizeof(aBuf), "%s: %i", Localize("Max Screenshots"), g_Config.m_ClAutoScreenshotMax); + else + str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Max Screenshots"), Localize("no limit")); + UI()->DoLabel(&Label, aBuf, 13.0f, -1); + g_Config.m_ClAutoScreenshotMax = static_cast(DoScrollbarH(&g_Config.m_ClAutoScreenshotMax, &Button, g_Config.m_ClAutoScreenshotMax/1000.0f)*1000.0f+0.1f); + } + + RenderLanguageSelection(List); +} + void CMenus::RenderSettings(CUIRect MainView) { static int s_SettingsPage = 0; diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 08459abcd..4696bdcde 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -584,6 +584,12 @@ void CGameClient::OnStateChange(int NewState, int OldState) void CGameClient::OnShutdown() {} void CGameClient::OnEnterGame() {} +void CGameClient::OnGameOver() +{ + if(Client()->State() != IClient::STATE_DEMOPLAYBACK) + Client()->AutoScreenshot_Start(); +} + void CGameClient::OnRconLine(const char *pLine) { m_pGameConsole->PrintLine(CGameConsole::CONSOLETYPE_REMOTE, pLine); @@ -769,7 +775,13 @@ void CGameClient::OnNewSnapshot() } } else if(Item.m_Type == NETOBJTYPE_GAME) + { + static int s_GameOver = 0; m_Snap.m_pGameobj = (CNetObj_Game *)pData; + if(s_GameOver == 0 && m_Snap.m_pGameobj->m_GameOver != 0) + OnGameOver(); + s_GameOver = m_Snap.m_pGameobj->m_GameOver; + } else if(Item.m_Type == NETOBJTYPE_FLAG) m_Snap.m_paFlags[Item.m_Id%2] = (const CNetObj_Flag *)pData; } diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index d60fef2a6..2f8e21ea2 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -180,6 +180,7 @@ public: virtual void OnShutdown(); virtual void OnEnterGame(); virtual void OnRconLine(const char *pLine); + virtual void OnGameOver(); virtual const char *GetItemName(int Type); virtual const char *Version(); diff --git a/src/game/editor/ed_editor.cpp b/src/game/editor/ed_editor.cpp index bb9a17212..b0ff42b29 100644 --- a/src/game/editor/ed_editor.cpp +++ b/src/game/editor/ed_editor.cpp @@ -3306,7 +3306,7 @@ void CEditor::UpdateAndRender() if(Input()->KeyDown(KEY_F10)) { - Graphics()->TakeScreenshot(); + Graphics()->TakeScreenshot(0); m_ShowMousePointer = true; }