Difference between revisions of "Animated Menu Background"

From Valve Developer Community
Jump to: navigation, search
(Initial write-up for the "Animated Menu Background" page.)
 
m ("SetZPos( -1 );" has been set in the menu_background.cpp file instead)
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
{{Note|This implementation has some issues, and we need your help! Please check out "Problem 4" at the bottom of the page.}}
 
 
 
 
== What Is This? ==
 
== What Is This? ==
  
 
This implementation allows you to use a .bik file as your main menu's background. Similar to what's seen in Left 4 Dead 2 and Portal 2.
 
This implementation allows you to use a .bik file as your main menu's background. Similar to what's seen in Left 4 Dead 2 and Portal 2.
  
<gallery caption="Examples" widths="512px" heights="384px" perrow="2" mode="packed">
+
<gallery caption="Examples" widths="800" heights="600px" perrow="2" mode="packed">
 
File:Small AnimatedBackgroundL4D2.gif
 
File:Small AnimatedBackgroundL4D2.gif
 
File:Small_AnimatedBackgroundP2.gif
 
File:Small_AnimatedBackgroundP2.gif
Line 36: Line 32:
 
Then at the bottom of the '''PostInit()''' function, add this:
 
Then at the bottom of the '''PostInit()''' function, add this:
 
<pre>
 
<pre>
#ifdef SDK_DLL
+
SwapDisconnectCommand();
SwapDisconnectCommand();
 
#endif
 
 
</pre>
 
</pre>
  
Now head over to '''clientmode_sdk.cpp''', and add this as the last include at the top of the file:
+
Now head over to '''baseviewport.cpp''', and add this at the top:
 
<pre>
 
<pre>
// memdbgon must be the last include file in a .cpp file!!!
+
#include "../menu_background.h"
#include "tier0/memdbgon.h"
 
 
</pre>
 
</pre>
  
Now head over to '''sdkviewport.cpp''', and again add this at the top:
+
In the same file, add this in the constructor ('''CBaseViewport::CBaseViewport()'''):
 
<pre>
 
<pre>
#include "menu_background.h"
+
m_pMainMenuPanel = NULL;
 
 
// memdbgon must be the last include file in a .cpp file!!!
 
#include "tier0/memdbgon.h"
 
 
</pre>
 
</pre>
  
In the same file, add this:
+
Add this in the destructor ('''CBaseViewport::~CBaseViewport()'''):
 
<pre>
 
<pre>
SDKViewport::SDKViewport()
+
if ( !m_bHasParent && m_pMainMenuPanel )
 
{
 
{
m_pMainMenuPanel = NULL;
+
m_pMainMenuPanel->MarkForDeletion();
 
}
 
}
 +
m_pMainMenuPanel = NULL;
 +
</pre>
  
SDKViewport::~SDKViewport()
+
Add this in the '''Start''' function ('''CBaseViewport::Start(...)'''):
{
+
<pre>
if ( !m_bHasParent && m_pMainMenuPanel )
+
m_pMainMenuPanel = new CMainMenu( NULL, NULL );
{
+
m_pMainMenuPanel->SetZPos( 500 );
m_pMainMenuPanel->MarkForDeletion();
+
m_pMainMenuPanel->SetVisible( false );
}
+
m_pMainMenuPanel->StartVideo();
m_pMainMenuPanel = NULL;
 
}
 
 
 
void SDKViewport::Start(IGameUIFuncs *pGameUIFuncs, IGameEventManager2 *pGameEventManager)
 
{
 
m_pMainMenuPanel = new CMainMenu( NULL, NULL );
 
m_pMainMenuPanel->SetZPos( 500 );
 
m_pMainMenuPanel->SetVisible( false );
 
m_pMainMenuPanel->StartVideo();
 
BaseClass::Start(pGameUIFuncs, pGameEventManager);
 
}
 
 
</pre>
 
</pre>
  
Above
+
Add this in the '''OnScreenSizeChanged''' function ('''CBaseViewport::OnScreenSizeChanged()'''):
 
 
 
<pre>
 
<pre>
void SDKViewport::ApplySchemeSettings( vgui::IScheme *pScheme )
+
bool bRestartMainMenuVideo = false;
 +
if (m_pMainMenuPanel)
 +
bRestartMainMenuVideo = m_pMainMenuPanel->IsVideoPlaying();
 +
m_pMainMenuPanel = new CMainMenu( NULL, NULL );
 +
m_pMainMenuPanel->SetZPos( 500 );
 +
m_pMainMenuPanel->SetVisible( false );
 +
if (bRestartMainMenuVideo)
 +
m_pMainMenuPanel->StartVideo();
 
</pre>
 
</pre>
  
Then below that function, add:
+
Add this in the '''RemoveAllPanels''' function ('''CBaseViewport::RemoveAllPanels( void )'''):
 
<pre>
 
<pre>
void SDKViewport::OnScreenSizeChanged(int iOldWide, int iOldTall)
+
if (m_pMainMenuPanel)
 
{
 
{
bool bRestartMainMenuVideo = false;
+
m_pMainMenuPanel->MarkForDeletion();
if (m_pMainMenuPanel)
+
m_pMainMenuPanel = NULL;
bRestartMainMenuVideo = m_pMainMenuPanel->IsVideoPlaying();
 
BaseClass::OnScreenSizeChanged(iOldWide, iOldTall);
 
m_pMainMenuPanel = new CMainMenu( NULL, NULL );
 
m_pMainMenuPanel->SetZPos( 500 );
 
m_pMainMenuPanel->SetVisible( false );
 
if (bRestartMainMenuVideo)
 
m_pMainMenuPanel->StartVideo();
 
}
 
 
 
void SDKViewport::RemoveAllPanels( void)
 
{
 
if (m_pMainMenuPanel)
 
{
 
m_pMainMenuPanel->MarkForDeletion();
 
m_pMainMenuPanel = NULL;
 
}
 
BaseClass::RemoveAllPanels();
 
 
}
 
}
 
</pre>
 
</pre>
  
And below the '''GetDeathMessageStartHeight( void )''' function add this:
+
Below the '''GetDeathMessageStartHeight( void )''' function add these:
 
<pre>
 
<pre>
void SDKViewport::StartMainMenuVideo()
+
void CBaseViewport::StartMainMenuVideo()
 
{
 
{
 
if (m_pMainMenuPanel)
 
if (m_pMainMenuPanel)
Line 121: Line 91:
 
}
 
}
  
void SDKViewport::StopMainMenuVideo()
+
void CBaseViewport::StopMainMenuVideo()
 
{
 
{
 
if (m_pMainMenuPanel)
 
if (m_pMainMenuPanel)
Line 128: Line 98:
 
</pre>
 
</pre>
  
Now head over to '''sdkviewport.h''', add this:
+
Now head over to '''baseviewport.h''', add these:
 
<pre>
 
<pre>
public:
 
SDKViewport();
 
~SDKViewport();
 
</pre>
 
 
Above
 
 
<pre>
 
public:
 
IViewPortPanel* CreatePanelByName(const char *szPanelName);
 
...
 
</pre>
 
 
In the same file, add these:
 
<pre>
 
virtual void Start( IGameUIFuncs *pGameUIFuncs, IGameEventManager2 *pGameEventManager );
 
virtual void OnScreenSizeChanged(int iOldWide, int iOldTall);
 
virtual void RemoveAllPanels( void);
 
 
void StartMainMenuVideo();
 
void StartMainMenuVideo();
 
void StopMainMenuVideo();
 
void StopMainMenuVideo();
Line 153: Line 105:
  
 
Below
 
Below
 
 
<pre>
 
<pre>
public:
+
virtual int GetDeathMessageStartHeight( void );
IViewPortPanel* CreatePanelByName(const char *szPanelName);
 
 
</pre>
 
</pre>
 
{{Note|Preferably in the same order as the functions seen in the .cpp file.}}
 
  
 
After the last function under '''public:''', add:
 
After the last function under '''public:''', add:
Line 167: Line 115:
 
</pre>
 
</pre>
  
Now head over to '''convar.h''', and make this public (protected: -> public:):
+
Now head over to '''convar.h''', and make this public (protected -> public):
 
<pre>
 
<pre>
 
protected:
 
protected:
Line 175: Line 123:
 
== What Next? ==
 
== What Next? ==
  
 +
=== The Bink File ===
 
Now that you're done with the implementation, you'll need a .bik file to play as your background.
 
Now that you're done with the implementation, you'll need a .bik file to play as your background.
  
Line 183: Line 132:
 
Once you've got your .bik file ready, rename it to '''mainmenu.bik''', and place it in your mod's media folder. If a media folder doesn't exist, create one.
 
Once you've got your .bik file ready, rename it to '''mainmenu.bik''', and place it in your mod's media folder. If a media folder doesn't exist, create one.
  
== The Problems ==
+
=== The Chapter Images ===
 
+
You might notice that your chapter images are all white now, this can be fixed by adding this to your to your chapter's VMT file:
=== Problem 1: ===
 
===== Solution: =====
 
In your Client project, right click "Source Files" -> Add -> Existing Item, then navigate to '''src/game/client/sdk/''' and add '''clientmode_sdk.cpp''' and '''src/game/client/'''.
 
 
 
===== Optional Solution: =====
 
Open your mod's .vpc file in '''src/game/client/''', and add these two lines:
 
<pre>
 
$File "sdk\clientmode_sdk.cpp"
 
$File "sdk\vgui\sdkviewport.cpp"
 
</pre>
 
 
 
Under
 
 
 
<pre>
 
$Folder "Source Files"
 
</pre>
 
 
 
{{Note|If you don't have one for your mod, open '''client_hl2.vpc''' or '''client_episodic.vpc''' depending on which game your mod is for.}}
 
{{Note|If you've never edited a .vpc file before, close Visual Studio after you've saved the .vpc changes, go to the '''src''' folder and run '''creategameprojects.bat''' before reopening your solution.}}
 
 
 
=== Problem 2: ===
 
While compiling, if you run into this error:
 
<pre>
 
Cannot open include file: 'sdk_shareddefs.h': No such file or directory (menu_background.cpp)
 
</pre>
 
 
 
Head back into '''sdkviewport.h''', and turn this:
 
<pre>
 
#include "sdk_shareddefs.h"
 
</pre>
 
 
 
Into this:
 
 
 
<pre>
 
#include "../../shared/sdk/sdk_shareddefs.h"
 
</pre>
 
 
 
Similarly, if you're running into this:
 
<pre>
 
Cannot open include file: 'sdkviewport.h': No such file or directory (sdk\clientmode_sdk.cpp)
 
</pre>
 
 
 
Go to '''clientmode_sdk.h''', and turn this:
 
<pre>
 
#include "sdkviewport.h"
 
</pre>
 
 
 
Into this:
 
 
 
<pre>
 
#include "vgui/sdkviewport.h"
 
</pre>
 
 
 
=== Problem 3 (temporary fix): ===
 
While compiling, if you run into these errors:
 
 
<pre>
 
<pre>
clientmode_hlnormal.obj : error LNK2005: "class IClientMode * __cdecl GetClientModeNormal(void)" (?GetClientModeNormal@@YAPAVIClientMode@@XZ) already defined in clientmode_sdk.obj
+
"$ignorez" "1"
hl2_clientmode.obj : error LNK2005: "class IVModeManager * modemanager" (?modemanager@@3PAVIVModeManager@@A) already defined in clientmode_sdk.obj
 
hl2_clientmode.obj : error LNK2005: "class ConVar default_fov" (?default_fov@@3VConVar@@A) already defined in clientmode_sdk.obj
 
 
</pre>
 
</pre>
  
Go to '''hl2_clientmode.cpp''', and at the top comment out this line:
+
Example of working VMT chapter file:
 
<pre>
 
<pre>
ConVar default_fov( "default_fov", "75", FCVAR_CHEAT );
+
"UnlitGeneric"
</pre>
 
 
 
Then scroll down to the bottom and comment out these lines:
 
 
 
<pre>
 
static CHLModeManager g_HLModeManager;
 
IVModeManager *modemanager = &g_HLModeManager;
 
</pre>
 
 
 
Now go to '''clientmode_hlnormal.cpp''', and comment out this function:
 
<pre>
 
IClientMode *GetClientModeNormal()
 
 
{
 
{
static ClientModeHLNormal g_ClientModeNormal;
+
"$baseTexture" "VGUI/chapters/chapterX"
return &g_ClientModeNormal;
+
"$vertexalpha" 1
 +
"$gammaColorRead" "1"
 +
"$linearWrite" "1"
 +
"$ignorez" "1"
 
}
 
}
 
</pre>
 
</pre>
  
This is a really bad solution to this problem. If you know of a better solution to this problem, please edit the page with the appropriate information on how to do so!
+
<gallery caption="Left: $ignorez 0 | Right: $ignorez 1" widths="600" heights="318px" perrow="2" mode="packed">
 
 
=== Problem 4: ===
 
 
 
Once this is implemented, you'll notice that your main menu's title text is gone and that your chapter images are all white.
 
 
 
<gallery widths="400px" heights="300px" perrow="2" mode="nolines">
 
File:AnimatedMainMenuBackground-issue01.png
 
 
File:AnimatedMainMenuBackground-issue02.png
 
File:AnimatedMainMenuBackground-issue02.png
 +
File:AnimatedMainMenuBackground-issue02-fixed-single.png
 
</gallery>
 
</gallery>
 
If anyone knows how to get these issues fixed, please do edit this page with the appropriate information on how to do so!
 
  
 
== Conclusion ==
 
== Conclusion ==
Line 285: Line 160:
  
 
This is currently only tested on the SP branch of Source SDK 2013. The MP branch and Source SDK 2007 remains untested as of writing this article.
 
This is currently only tested on the SP branch of Source SDK 2013. The MP branch and Source SDK 2007 remains untested as of writing this article.
 +
 +
== Special Thanks ==
 +
Special thanks to Taz, OzxyBox and Gocnak from the Source Modding Community for solving the problems this implementation was originally facing!
  
 
[[Category:Programming]]
 
[[Category:Programming]]
 
[[Category:Free source code]]
 
[[Category:Free source code]]

Latest revision as of 14:11, 13 September 2018

What Is This?

This implementation allows you to use a .bik file as your main menu's background. Similar to what's seen in Left 4 Dead 2 and Portal 2.

The Implementation

First off you'll need these two files:


Which you'll put into src/game/client/


Once that's done, open up cdll_client_int.cpp and add this:

void SwapDisconnectCommand();

Above

void CHLClient::PostInit()

Then at the bottom of the PostInit() function, add this:

SwapDisconnectCommand();

Now head over to baseviewport.cpp, and add this at the top:

#include "../menu_background.h"

In the same file, add this in the constructor (CBaseViewport::CBaseViewport()):

m_pMainMenuPanel = NULL;

Add this in the destructor (CBaseViewport::~CBaseViewport()):

if ( !m_bHasParent && m_pMainMenuPanel )
{
	m_pMainMenuPanel->MarkForDeletion();
}
m_pMainMenuPanel = NULL;

Add this in the Start function (CBaseViewport::Start(...)):

m_pMainMenuPanel = new CMainMenu( NULL, NULL );
m_pMainMenuPanel->SetZPos( 500 );
m_pMainMenuPanel->SetVisible( false );
m_pMainMenuPanel->StartVideo();

Add this in the OnScreenSizeChanged function (CBaseViewport::OnScreenSizeChanged()):

bool bRestartMainMenuVideo = false;
if (m_pMainMenuPanel)
	bRestartMainMenuVideo = m_pMainMenuPanel->IsVideoPlaying();
m_pMainMenuPanel = new CMainMenu( NULL, NULL );
m_pMainMenuPanel->SetZPos( 500 );
m_pMainMenuPanel->SetVisible( false );
if (bRestartMainMenuVideo)
	m_pMainMenuPanel->StartVideo();

Add this in the RemoveAllPanels function (CBaseViewport::RemoveAllPanels( void )):

if (m_pMainMenuPanel)
{
	m_pMainMenuPanel->MarkForDeletion();
	m_pMainMenuPanel = NULL;
}

Below the GetDeathMessageStartHeight( void ) function add these:

void CBaseViewport::StartMainMenuVideo()
{
	if (m_pMainMenuPanel)
		m_pMainMenuPanel->StartVideo();
}

void CBaseViewport::StopMainMenuVideo()
{
	if (m_pMainMenuPanel)
		m_pMainMenuPanel->StopVideo();
}

Now head over to baseviewport.h, add these:

void StartMainMenuVideo();
void StopMainMenuVideo();

Below

virtual int GetDeathMessageStartHeight( void );	

After the last function under public:, add:

private:
	class CMainMenu* m_pMainMenuPanel;

Now head over to convar.h, and make this public (protected -> public):

protected:
	virtual void Create( const char *pName, const char *pHelpString = 0, int flags = 0 );

What Next?

The Bink File

Now that you're done with the implementation, you'll need a .bik file to play as your background.

I won't show you how to make your own .bik file, but I can recommend following this guide for that:


Once you've got your .bik file ready, rename it to mainmenu.bik, and place it in your mod's media folder. If a media folder doesn't exist, create one.

The Chapter Images

You might notice that your chapter images are all white now, this can be fixed by adding this to your to your chapter's VMT file:

"$ignorez" "1"

Example of working VMT chapter file:

"UnlitGeneric"
{
	"$baseTexture" "VGUI/chapters/chapterX"
	"$vertexalpha" 1
	"$gammaColorRead" "1"
	"$linearWrite" "1"
	"$ignorez" "1"
}

Conclusion

And that's it, try launching your mod to see if it works!

This is currently only tested on the SP branch of Source SDK 2013. The MP branch and Source SDK 2007 remains untested as of writing this article.

Special Thanks

Special thanks to Taz, OzxyBox and Gocnak from the Source Modding Community for solving the problems this implementation was originally facing!