| DemoGL::Using::Creating a simple screensaver |
As the basis of the simple screensaver, we use the simple application created in Creating a simple application. What Windows does when a screensaver is executed, is passing certain parameters on the commandline when calling the executable. In fact, a screensaver is just a normal .exe but with a different extension: .scr. A normal executable doesn't react on the screensaver commandline parameters and will not behave as a screensaver. DemoGL provides an easy way to determine which commandline parameters were passed and thus how to run the screensaver: as preview in the tiny preview window on the screensaver tab in Display Properties, as a normal screensaver when called by Windows when the timeout set on the screensaver tab in Display Properties or in configuration mode: when the user selects 'configure' in a popup menu or 'settings' on the screensaver tab in Display Properties.
First, the commandline passed to the WinMain function should be passed and the parameters should be stored in a structure for further interpretation. The API function DEMOGL_ParseScreenSaverCL is made for that:
int APIENTRY
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
// ... other code
// Declaration of the structure, which will
// contain the parsed screensaver commandline
// parameters.
SScreenSaverCLParams *pSSCLParams;
int iRunType;
// ... other code
// Parse commandline for screensaver exectype.
// lpCmdLine is a parameter of WinMain()
pSSCLParams=DEMOGL_ParseScreenSaverCL(lpCmdLine);
// Determine the runtype, using the parsed commandline
// parameters.
switch(pSSCLParams->iSaverExecType)
{
case DGL_SSAVERET_CONFIG:
{
/////////////////////////
// Insert your own configwindow initialisation and
// start up code HERE
/////////////////////////
iRunType=RUNTYPE_SAVER_CONFIG;
}; break;
case DGL_SSAVERET_NORMAL:
{
iRunType=RUNTYPE_SAVER_NORMAL;
}; break;
case DGL_SSAVERET_PREVIEW:
{
iRunType=RUNTYPE_SAVER_PREVIEW;
}; break;
default:
{
// should not run, unknown or unsupported screensaver type.
iRunType=RUNTYPE_UNKNOWN; // will return immediately
}; break;
}
// we've now gathered enough information to run this application
// as a screensaver. Start the application as we did in the
// application, now passing the iRunType variable
DEMOGL_AppRun(hInstance, &sdStartupDatValues, "DemoGL Example",
false,0,0,iRunType);
// ... other code
}
These are the changes made to WinMain to make a normal application behave as a win32 screensaver. Because these changes are standard, you can just copy/paste them in every time you change your application into a screensaver. The reason why there is a difference between the DGL_SSAVERET_* constants and the RUNTYPE_SAVER_* constants is that the RUNTYPE_SAVER_* are part of a larger collection than the DGL_SSAVERET_* constants and are semantically used for different things, that's why there are different constants defined and that's also the reason why DEMOGL_ParseScreenSaverCL doesn't return the RUNTYPE_SAVER_* type but the determined execution type of the screensaver.
A screensaver should run forever and a DemoGL powered win32 application will most of the time end after a predefined amount of time, due to the fact that all content is shown and the audiovisual experience is over. To make the win32 application loop, add a TLE at the end of the timeline so DemoGL will restart the application. This TLE should execute the RESTART command with the _SYSTEM object. See for more information the _SYSTEM script syntax.
Below is the complete mydemo.cpp file, now modified to act like a screensaver.
// mydemo.cpp file, which illustrates the basic code needed for
// a DemoGL application
////////////////////////////////////////////////////////////////
// Exclude rarely-used stuff from Windows headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// include DemoGL headerfile
#include "DemoGL_DLL.h"
// Include all effect headers
#include "CSplash.h"
////////////////////////////////////////
// C O D E //
////////////////////////////////////////
// Purpose: main routine that is called when the
// application is started.
int APIENTRY
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
// declare pointers to all effects
CSplash *pSplash;
// necessary objects and variables
SStartupDat sdStartupDatValues;
SScreenSaverCLParams *pSSCLParams;
int iRunType;
// create objects of all effects
pSplash = new CSplash();
// set variables that will affect execution. We will
// load from a directory. For illustration purposes
// we set all variables to a certain value
DEMOGL_SetVariable(DGL_VF_VSYNC,true);
DEMOGL_SetVariable(DGL_VF_FILESRC,DGL_FSRC_LOADFROMDIR);
DEMOGL_SetVariable(DGL_VF_SRCDIR,"demodat");
DEMOGL_SetVariable(DGL_VF_DATAFILENAME,NULL);
DEMOGL_SetVariable(DGL_VF_SCRIPTFILENAME,"demoflow");
DEMOGL_SetVariable(DGL_VF_SHOWFPS,false);
DEMOGL_SetVariable(DGL_VF_NEVERSHOWFPS,false);
DEMOGL_SetVariable(DGL_VF_NEVERSHOWCONSOLE,false);
DEMOGL_SetVariable(DGL_VF_SHOWDEBUGINFO,false);
DEMOGL_SetVariable(DGL_VF_NEVERSHOWDEBUGINFO,false);
DEMOGL_SetVariable(DGL_VF_NEVERRESCALETEXTURES,false);
DEMOGL_SetVariable(DGL_VF_QUICKBOOT,false);
// Set the startup variables. Do that via a structure
// that we'll pass to DEMOGL_AppRun() function
sdStartupDatValues.m_bDQ32bit=true;
sdStartupDatValues.m_bFullScreen=true;
sdStartupDatValues.m_bRescaleTextures=true;
sdStartupDatValues.m_bSaveInRegistry=true;
sdStartupDatValues.m_bTQ32bit=true;
sdStartupDatValues.m_iResolution=DGL_RES_800x600;
strncpy(sdStartupDatValues.m_sDemoName,"My Demo",DGL_SD_STRINGLENGTH);
strncpy(sdStartupDatValues.m_sReleasedBy,"Me, myself and I",
DGL_SD_STRINGLENGTH);
sdStartupDatValues.m_bSound=true;
sdStartupDatValues.m_bSS_3DSound=true;
sdStartupDatValues.m_bSS_LowQuality=false;
sdStartupDatValues.m_bSS_16bit=true;
sdStartupDatValues.m_bSS_A3D=false;
sdStartupDatValues.m_bSS_EAX=true;
sdStartupDatValues.m_bSS_Stereo=true;
sdStartupDatValues.m_iSS_OverallVolume=90;
sdStartupDatValues.m_iSS_SoundDevice=0;
// register all effectobjects with DemoGL
DEMOGL_EffectRegister(pSplash, "SPLASH");
// Enable loading progress bar. This example bar is located at
// the bottom of the screen.
DEMOGL_LoadingPBEnable(DGL_CNTRL_PGB_LINEAR, 1.0f, 0.02f, 0.0f, 0.00f);
DEMOGL_LoadingPBSetAppearance(true, false, GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR, 1.0f, 0.5f,0.5f,0.5f, 1.0f,1.0f,1.0f);
// Parse commandline for screensaver exectype.
// lpCmdLine is a parameter of WinMain()
pSSCLParams=DEMOGL_ParseScreenSaverCL(lpCmdLine);
// Determine the runtype, using the parsed commandline
// parameters.
switch(pSSCLParams->iSaverExecType)
{
case DGL_SSAVERET_CONFIG:
{
/////////////////////////
// Insert your own configwindow initialisation and
// start up code HERE
/////////////////////////
iRunType=RUNTYPE_SAVER_CONFIG;
}; break;
case DGL_SSAVERET_NORMAL:
{
iRunType=RUNTYPE_SAVER_NORMAL;
}; break;
case DGL_SSAVERET_PREVIEW:
{
iRunType=RUNTYPE_SAVER_PREVIEW;
}; break;
default:
{
// should not run, unknown or unsupported screensaver type.
iRunType=RUNTYPE_UNKNOWN; // will return immediately
}; break;
}
// Start The Demo! We won't return until the demo ends (by
// userinteraction or by script) or when a fatal error occurs.
DEMOGL_AppRun(hInstance, &sdStartupDatValues, "DemoGL Example", false,
0,0, iRunType);
// End it. Call this routine to signal demogl it's all over and it
// should release claimed resources.
DEMOGL_AppEnd();
// delete all Effectobjects
delete pSplash;
// end.
return 0;
}
Last changed on 12-mar-2001
©1999-2001 Solutions Design