1475 lines
44 KiB
C++
1475 lines
44 KiB
C++
|
//-----------------------------------------------------------------------------
|
||
|
// File: FlyingObjects.cpp
|
||
|
//
|
||
|
// Desc: Fun screen saver
|
||
|
//
|
||
|
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
#include <windows.h>
|
||
|
#include <tchar.h>
|
||
|
#include <d3d8.h>
|
||
|
#include <d3dx8.h>
|
||
|
#include <d3d8rgbrast.h>
|
||
|
#include <time.h>
|
||
|
#include <stdio.h>
|
||
|
#include <commctrl.h>
|
||
|
#include <scrnsave.h>
|
||
|
#include "d3dsaver.h"
|
||
|
#include "FlyingObjects.h"
|
||
|
#include "mesh.h"
|
||
|
#include "Resource.h"
|
||
|
#include "dxutil.h"
|
||
|
|
||
|
|
||
|
extern void updateStripScene(int flags, FLOAT fElapsedTime);
|
||
|
extern void updateDropScene(int flags, FLOAT fElapsedTime);
|
||
|
extern void updateLemScene(int flags, FLOAT fElapsedTime);
|
||
|
extern void updateExplodeScene(int flags, FLOAT fElapsedTime);
|
||
|
extern void updateWinScene(int flags, FLOAT fElapsedTime);
|
||
|
extern void updateWin2Scene(int flags, FLOAT fElapsedTime);
|
||
|
extern void updateTexScene(int flags, FLOAT fElapsedTime);
|
||
|
extern BOOL initStripScene(void);
|
||
|
extern BOOL initDropScene(void);
|
||
|
extern BOOL initLemScene(void);
|
||
|
extern BOOL initExplodeScene(void);
|
||
|
extern BOOL initWinScene(void);
|
||
|
extern BOOL initWin2Scene(void);
|
||
|
extern BOOL initTexScene(void);
|
||
|
extern void delStripScene(void);
|
||
|
extern void delDropScene(void);
|
||
|
extern void delLemScene(void);
|
||
|
extern void delExplodeScene(void);
|
||
|
extern void delWinScene(void);
|
||
|
extern void delWin2Scene(void);
|
||
|
extern void delTexScene(void);
|
||
|
|
||
|
typedef void (*PTRUPDATE)(int flags, FLOAT fElapsedTime);
|
||
|
typedef void (*ptrdel)();
|
||
|
typedef BOOL (*ptrinit)();
|
||
|
|
||
|
// Each screen saver style puts its hook functions into the function
|
||
|
// arrays below. A consistent ordering of the functions is required.
|
||
|
|
||
|
static PTRUPDATE updateFuncs[] =
|
||
|
{/*updateWinScene,*/ updateWin2Scene, updateExplodeScene,updateStripScene, updateStripScene,
|
||
|
updateDropScene, updateLemScene, updateTexScene};
|
||
|
|
||
|
static ptrdel delFuncs[] =
|
||
|
{/*delWinScene,*/ delWin2Scene, delExplodeScene, delStripScene, delStripScene,
|
||
|
delDropScene, delLemScene, delTexScene};
|
||
|
|
||
|
static ptrinit initFuncs[] =
|
||
|
{/*initWinScene,*/ initWin2Scene, initExplodeScene, initStripScene, initStripScene,
|
||
|
initDropScene, initLemScene, initTexScene};
|
||
|
|
||
|
static int idsStyles[] =
|
||
|
{IDS_LOGO, IDS_EXPLODE, IDS_RIBBON, IDS_2RIBBON,
|
||
|
IDS_SPLASH, IDS_TWIST, IDS_FLAG};
|
||
|
|
||
|
#define MAX_TYPE ( sizeof(initFuncs) / sizeof(ptrinit) - 1 )
|
||
|
|
||
|
// Each screen saver style can choose which dialog box controls it wants
|
||
|
// to use. These flags enable each of the controls. Controls not choosen
|
||
|
// will be disabled.
|
||
|
|
||
|
#define OPT_COLOR_CYCLE 0x00000001
|
||
|
#define OPT_SMOOTH_SHADE 0x00000002
|
||
|
#define OPT_TESSEL 0x00000008
|
||
|
#define OPT_SIZE 0x00000010
|
||
|
#define OPT_TEXTURE 0x00000020
|
||
|
#define OPT_STD ( OPT_COLOR_CYCLE | OPT_SMOOTH_SHADE | OPT_TESSEL | OPT_SIZE )
|
||
|
|
||
|
static ULONG gflConfigOpt[] = {
|
||
|
// OPT_STD, // Windows logo
|
||
|
0, // New Windows logo
|
||
|
OPT_STD, // Explode
|
||
|
OPT_STD, // Strip
|
||
|
OPT_STD, // Strip
|
||
|
OPT_STD, // Drop
|
||
|
OPT_STD, // Twist (lemniscate)
|
||
|
OPT_SMOOTH_SHADE | OPT_TESSEL | OPT_SIZE | OPT_TEXTURE // Texture mapped flag
|
||
|
};
|
||
|
|
||
|
static void updateDialogControls(HWND hDlg);
|
||
|
|
||
|
CFlyingObjectsScreensaver* g_pMyFlyingObjectsScreensaver = NULL;
|
||
|
|
||
|
INT g_xScreenOrigin = 0;
|
||
|
INT g_yScreenOrigin = 0;
|
||
|
INT g_iDevice = -1;
|
||
|
FLOATRECT* g_pFloatRect = NULL;
|
||
|
BOOL gbBounce = FALSE; // floating window bounce off side
|
||
|
|
||
|
|
||
|
// Global message loop variables.
|
||
|
D3DMATERIAL8 Material[16];
|
||
|
#ifdef MEMDEBUG
|
||
|
ULONG totalMem = 0;
|
||
|
#endif
|
||
|
|
||
|
void (*updateSceneFunc)(int flags, FLOAT fElapsedTime); // current screen saver update function
|
||
|
void (*delSceneFunc)(void); // current screen saver deletion function
|
||
|
BOOL bColorCycle = FALSE; // color cycling flag
|
||
|
DeviceObjects* g_pDeviceObjects = NULL;
|
||
|
BOOL g_bMoveToOrigin = FALSE;
|
||
|
BOOL g_bAtOrigin = FALSE;
|
||
|
BOOL bSmoothShading = TRUE; // smooth shading flag
|
||
|
UINT uSize = 100; // object size
|
||
|
float fTesselFact = 2.0f; // object tessalation
|
||
|
int UpdateFlags = 0; // extra data sent to update function
|
||
|
int Type = 0; // screen saver index (into function arrays)
|
||
|
|
||
|
LPDIRECT3DDEVICE8 m_pd3dDevice = NULL;
|
||
|
LPDIRECT3DINDEXBUFFER8 m_pIB = NULL;
|
||
|
LPDIRECT3DVERTEXBUFFER8 m_pVB = NULL;
|
||
|
LPDIRECT3DVERTEXBUFFER8 m_pVB2 = NULL;
|
||
|
|
||
|
// Texture file information
|
||
|
TEXFILE gTexFile = {0};
|
||
|
|
||
|
// Lighting properties.
|
||
|
|
||
|
static const RGBA lightAmbient = {0.21f, 0.21f, 0.21f, 1.0f};
|
||
|
static const RGBA light0Ambient = {0.0f, 0.0f, 0.0f, 1.0f};
|
||
|
static const RGBA light0Diffuse = {0.7f, 0.7f, 0.7f, 1.0f};
|
||
|
static const RGBA light0Specular = {1.0f, 1.0f, 1.0f, 1.0f};
|
||
|
static const FLOAT light0Pos[] = {100.0f, 100.0f, 100.0f, 0.0f};
|
||
|
|
||
|
// Material properties.
|
||
|
|
||
|
static RGBA matlColors[7] = {{1.0f, 0.0f, 0.0f, 1.0f},
|
||
|
{0.0f, 1.0f, 0.0f, 1.0f},
|
||
|
{0.0f, 0.0f, 1.0f, 1.0f},
|
||
|
{1.0f, 1.0f, 0.0f, 1.0f},
|
||
|
{0.0f, 1.0f, 1.0f, 1.0f},
|
||
|
{1.0f, 0.0f, 1.0f, 1.0f},
|
||
|
{0.235f, 0.0f, 0.78f, 1.0f},
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
static D3DMATERIAL8 s_mtrl =
|
||
|
{
|
||
|
1.0f, 1.0f, 1.0f, 1.0f, // Diffuse
|
||
|
1.0f, 1.0f, 1.0f, 1.0f, // Ambient
|
||
|
1.0f, 1.0f, 1.0f, 1.0f, // Specular
|
||
|
0.0f, 0.0f, 0.0f, 0.0f, // Emissive
|
||
|
30.0f // Power
|
||
|
};
|
||
|
|
||
|
|
||
|
#define BUF_SIZE 255
|
||
|
TCHAR g_szSectName[BUF_SIZE];
|
||
|
TCHAR g_szFname[BUF_SIZE];
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: myglMaterialfv()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
VOID myglMaterialfv(INT face, INT pname, FLOAT* params)
|
||
|
{
|
||
|
if( pname == GL_AMBIENT_AND_DIFFUSE)
|
||
|
{
|
||
|
s_mtrl.Ambient.r = s_mtrl.Diffuse.r = params[0];
|
||
|
s_mtrl.Ambient.g = s_mtrl.Diffuse.g = params[1];
|
||
|
s_mtrl.Ambient.b = s_mtrl.Diffuse.b = params[2];
|
||
|
s_mtrl.Ambient.a = s_mtrl.Diffuse.a = params[3];
|
||
|
}
|
||
|
else if( pname == GL_SPECULAR )
|
||
|
{
|
||
|
s_mtrl.Specular.r = params[0];
|
||
|
s_mtrl.Specular.g = params[1];
|
||
|
s_mtrl.Specular.b = params[2];
|
||
|
s_mtrl.Specular.a = params[3];
|
||
|
}
|
||
|
else if( pname == GL_SHININESS )
|
||
|
{
|
||
|
s_mtrl.Power = params[0];
|
||
|
}
|
||
|
|
||
|
m_pd3dDevice->SetMaterial(&s_mtrl);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: myglMaterialf()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
VOID myglMaterialf(INT face, INT pname, FLOAT param)
|
||
|
{
|
||
|
if( pname == GL_SHININESS )
|
||
|
{
|
||
|
s_mtrl.Power = param;
|
||
|
}
|
||
|
|
||
|
m_pd3dDevice->SetMaterial(&s_mtrl);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
* HsvToRgb
|
||
|
*
|
||
|
* HSV to RGB color space conversion. From pg. 593 of Foley & van Dam.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
void ss_HsvToRgb(float h, float s, float v, RGBA *color )
|
||
|
{
|
||
|
float i, f, p, q, t;
|
||
|
|
||
|
// set alpha value, so caller doesn't have to worry about undefined value
|
||
|
color->a = 1.0f;
|
||
|
|
||
|
if (s == 0.0f) // assume h is undefined
|
||
|
color->r = color->g = color->b = v;
|
||
|
else {
|
||
|
if (h >= 360.0f)
|
||
|
h = 0.0f;
|
||
|
h = h / 60.0f;
|
||
|
i = (float) floor(h);
|
||
|
f = h - i;
|
||
|
p = v * (1.0f - s);
|
||
|
q = v * (1.0f - (s * f));
|
||
|
t = v * (1.0f - (s * (1.0f - f)));
|
||
|
switch ((int)i) {
|
||
|
case 0:
|
||
|
color->r = v;
|
||
|
color->g = t;
|
||
|
color->b = p;
|
||
|
break;
|
||
|
case 1:
|
||
|
color->r = q;
|
||
|
color->g = v;
|
||
|
color->b = p;
|
||
|
break;
|
||
|
case 2:
|
||
|
color->r = p;
|
||
|
color->g = v;
|
||
|
color->b = t;
|
||
|
break;
|
||
|
case 3:
|
||
|
color->r = p;
|
||
|
color->g = q;
|
||
|
color->b = v;
|
||
|
break;
|
||
|
case 4:
|
||
|
color->r = t;
|
||
|
color->g = p;
|
||
|
color->b = v;
|
||
|
break;
|
||
|
case 5:
|
||
|
color->r = v;
|
||
|
color->g = p;
|
||
|
color->b = q;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void *SaverAlloc(ULONG size)
|
||
|
{
|
||
|
void *mPtr;
|
||
|
|
||
|
mPtr = malloc(size);
|
||
|
#ifdef MEMDEBUG
|
||
|
totalMem += size;
|
||
|
xprintf("malloc'd %x, size %d\n", mPtr, size);
|
||
|
#endif
|
||
|
return mPtr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void SaverFree(void *pMem)
|
||
|
{
|
||
|
#ifdef MEMDEBUG
|
||
|
totalMem -= _msize(pMem);
|
||
|
xprintf("free %x, size = %d, total = %d\n", pMem, _msize(pMem), totalMem);
|
||
|
#endif
|
||
|
free(pMem);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// Minimum and maximum image sizes
|
||
|
#define MINIMAGESIZE 10
|
||
|
#define MAXIMAGESIZE 100
|
||
|
|
||
|
|
||
|
// A slider range
|
||
|
typedef struct _RANGE
|
||
|
{
|
||
|
int min_val;
|
||
|
int max_val;
|
||
|
int step;
|
||
|
int page_step;
|
||
|
} RANGE;
|
||
|
|
||
|
RANGE complexity_range = {MINSUBDIV, MAXSUBDIV, 1, 2};
|
||
|
RANGE image_size_range = {MINIMAGESIZE, MAXIMAGESIZE, 1, 10};
|
||
|
|
||
|
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
* initMaterial
|
||
|
*
|
||
|
* Initialize the material properties.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
void initMaterial(int id, float r, float g, float b, float a)
|
||
|
{
|
||
|
Material[id].Ambient.r = r;
|
||
|
Material[id].Ambient.g = g;
|
||
|
Material[id].Ambient.b = b;
|
||
|
Material[id].Ambient.a = a;
|
||
|
|
||
|
Material[id].Diffuse.r = r;
|
||
|
Material[id].Diffuse.g = g;
|
||
|
Material[id].Diffuse.b = b;
|
||
|
Material[id].Diffuse.a = a;
|
||
|
|
||
|
Material[id].Specular.r = 1.0f;
|
||
|
Material[id].Specular.g = 1.0f;
|
||
|
Material[id].Specular.b = 1.0f;
|
||
|
Material[id].Specular.a = 1.0f;
|
||
|
|
||
|
Material[id].Power = 128.0f;
|
||
|
}
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
* _3dfo_Init
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
BOOL CFlyingObjectsScreensaver::_3dfo_Init(void *data)
|
||
|
{
|
||
|
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < 7; i++)
|
||
|
initMaterial(i, matlColors[i].r, matlColors[i].g,
|
||
|
matlColors[i].b, matlColors[i].a);
|
||
|
|
||
|
/*
|
||
|
// Set the OpenGL clear color to black.
|
||
|
|
||
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||
|
#ifdef SS_DEBUG
|
||
|
glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
|
||
|
#endif
|
||
|
|
||
|
// Enable the z-buffer.
|
||
|
|
||
|
glEnable(GL_DEPTH_TEST);
|
||
|
*/
|
||
|
// Select the shading model.
|
||
|
|
||
|
if (bSmoothShading)
|
||
|
{
|
||
|
m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_FLAT );
|
||
|
}
|
||
|
|
||
|
/* // Setup the OpenGL matrices.
|
||
|
|
||
|
glMatrixMode(GL_PROJECTION);
|
||
|
glLoadIdentity();
|
||
|
glMatrixMode(GL_MODELVIEW);
|
||
|
glLoadIdentity();
|
||
|
|
||
|
// Setup the lighting.
|
||
|
|
||
|
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (FLOAT *) &lightAmbient);
|
||
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
||
|
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
|
||
|
glLightfv(GL_LIGHT0, GL_AMBIENT, (FLOAT *) &light0Ambient);
|
||
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, (FLOAT *) &light0Diffuse);
|
||
|
glLightfv(GL_LIGHT0, GL_SPECULAR, (FLOAT *) &light0Specular);
|
||
|
glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
|
||
|
glEnable(GL_LIGHTING);
|
||
|
glEnable(GL_LIGHT0);
|
||
|
*/
|
||
|
|
||
|
// m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_COLORVALUE(lightAmbient.r,
|
||
|
// lightAmbient.g, lightAmbient.b, lightAmbient.a ) );
|
||
|
|
||
|
D3DLIGHT8 light;
|
||
|
ZeroMemory( &light, sizeof(D3DLIGHT8) );
|
||
|
light.Type = D3DLIGHT_POINT;
|
||
|
light.Range = 1000.0f;
|
||
|
light.Position.x = light0Pos[0];
|
||
|
light.Position.y = light0Pos[1];
|
||
|
light.Position.z = light0Pos[2];
|
||
|
light.Ambient.r = lightAmbient.r;
|
||
|
light.Ambient.g = lightAmbient.g;
|
||
|
light.Ambient.b = lightAmbient.b;
|
||
|
light.Ambient.a = light0Ambient.a;
|
||
|
light.Diffuse.r = light0Diffuse.r;
|
||
|
light.Diffuse.g = light0Diffuse.g;
|
||
|
light.Diffuse.b = light0Diffuse.b;
|
||
|
light.Diffuse.a = light0Diffuse.a;
|
||
|
light.Specular.r = light0Specular.r;
|
||
|
light.Specular.g = light0Specular.g;
|
||
|
light.Specular.b = light0Specular.b;
|
||
|
light.Specular.a = light0Specular.a;
|
||
|
light.Attenuation0 = 1.0f;
|
||
|
light.Attenuation1 = 0.0f;
|
||
|
light.Attenuation2 = 0.0f;
|
||
|
m_pd3dDevice->SetLight(0, &light);
|
||
|
m_pd3dDevice->LightEnable(0, TRUE);
|
||
|
|
||
|
// m_pd3dDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE);
|
||
|
|
||
|
// Setup the material properties.
|
||
|
m_pd3dDevice->SetMaterial( &Material[0] );
|
||
|
|
||
|
/* glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (FLOAT *) &Material[0].ks);
|
||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, (FLOAT *) &Material[0].specExp);
|
||
|
*/
|
||
|
// call specific objects init func
|
||
|
if (! (*initFuncs[Type])() )
|
||
|
return FALSE;
|
||
|
updateSceneFunc = updateFuncs[Type];
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
* WriteSettings
|
||
|
*
|
||
|
* Save the screen saver configuration option to the .INI file/registry.
|
||
|
*
|
||
|
* History:
|
||
|
* 10-May-1994 -by- Gilman Wong [gilmanw]
|
||
|
* Wrote it.
|
||
|
\**************************************************************************/
|
||
|
VOID CFlyingObjectsScreensaver::WriteSettings(HWND hDlg)
|
||
|
{
|
||
|
HKEY hkey;
|
||
|
|
||
|
if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, m_strRegPath,
|
||
|
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
|
||
|
{
|
||
|
int pos, options;
|
||
|
int optMask = 1;
|
||
|
|
||
|
bSmoothShading = IsDlgButtonChecked(hDlg, DLG_SETUP_SMOOTH);
|
||
|
bColorCycle = IsDlgButtonChecked(hDlg, DLG_SETUP_CYCLE);
|
||
|
options = bColorCycle;
|
||
|
options <<= 1;
|
||
|
options |= bSmoothShading;
|
||
|
DXUtil_WriteIntRegKey( hkey, TEXT("Options"), options );
|
||
|
|
||
|
Type = (int)SendDlgItemMessage(hDlg, DLG_SETUP_TYPES, CB_GETCURSEL,
|
||
|
0, 0);
|
||
|
DXUtil_WriteIntRegKey( hkey, TEXT("Type"), Type );
|
||
|
|
||
|
pos = ss_GetTrackbarPos( hDlg, DLG_SETUP_TESSEL );
|
||
|
DXUtil_WriteIntRegKey( hkey, TEXT("Tesselation"), pos );
|
||
|
|
||
|
pos = ss_GetTrackbarPos( hDlg, DLG_SETUP_SIZE );
|
||
|
DXUtil_WriteIntRegKey( hkey, TEXT("Size"), pos );
|
||
|
|
||
|
DXUtil_WriteStringRegKey( hkey, TEXT("Texture"), gTexFile.szPathName );
|
||
|
DXUtil_WriteIntRegKey( hkey, TEXT("TextureFileOffset"), gTexFile.nOffset );
|
||
|
|
||
|
WriteScreenSettings( hkey );
|
||
|
|
||
|
RegCloseKey( hkey );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
* SetupTrackbar
|
||
|
*
|
||
|
* Setup a common control trackbar
|
||
|
\**************************************************************************/
|
||
|
void
|
||
|
ss_SetupTrackbar( HWND hDlg, int item, int lo, int hi, int lineSize,
|
||
|
int pageSize, int pos )
|
||
|
{
|
||
|
SendDlgItemMessage(
|
||
|
hDlg,
|
||
|
item,
|
||
|
TBM_SETRANGE,
|
||
|
(WPARAM) TRUE,
|
||
|
(LPARAM) MAKELONG( lo, hi )
|
||
|
);
|
||
|
SendDlgItemMessage(
|
||
|
hDlg,
|
||
|
item,
|
||
|
TBM_SETPOS,
|
||
|
(WPARAM) TRUE,
|
||
|
(LPARAM) pos
|
||
|
);
|
||
|
SendDlgItemMessage(
|
||
|
hDlg,
|
||
|
item,
|
||
|
TBM_SETPAGESIZE,
|
||
|
(WPARAM) 0,
|
||
|
(LPARAM) pageSize
|
||
|
);
|
||
|
SendDlgItemMessage(
|
||
|
hDlg,
|
||
|
item,
|
||
|
TBM_SETLINESIZE,
|
||
|
(WPARAM) 0,
|
||
|
(LPARAM) lineSize
|
||
|
);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
* GetTrackbarPos
|
||
|
*
|
||
|
* Get the current position of a common control trackbar
|
||
|
\**************************************************************************/
|
||
|
int
|
||
|
ss_GetTrackbarPos( HWND hDlg, int item )
|
||
|
{
|
||
|
return
|
||
|
(int)SendDlgItemMessage(
|
||
|
hDlg,
|
||
|
item,
|
||
|
TBM_GETPOS,
|
||
|
0,
|
||
|
0
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
* setupDialogControls
|
||
|
*
|
||
|
* Setup the dialog controls initially.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
static void
|
||
|
setupDialogControls(HWND hDlg)
|
||
|
{
|
||
|
int pos;
|
||
|
|
||
|
InitCommonControls();
|
||
|
|
||
|
if (fTesselFact <= 1.0f)
|
||
|
pos = (int)(fTesselFact * 100.0f);
|
||
|
else
|
||
|
pos = 100 + (int) ((fTesselFact - 1.0f) * 100.0f);
|
||
|
|
||
|
ss_SetupTrackbar( hDlg, DLG_SETUP_TESSEL, 0, 200, 1, 10, pos );
|
||
|
|
||
|
ss_SetupTrackbar( hDlg, DLG_SETUP_SIZE, 0, 100, 1, 10, uSize );
|
||
|
|
||
|
updateDialogControls( hDlg );
|
||
|
}
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
* updateDialogControls
|
||
|
*
|
||
|
* Update the dialog controls based on the current global state.
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
|
||
|
static void
|
||
|
updateDialogControls(HWND hDlg)
|
||
|
{
|
||
|
CheckDlgButton(hDlg, DLG_SETUP_SMOOTH, bSmoothShading);
|
||
|
CheckDlgButton(hDlg, DLG_SETUP_CYCLE, bColorCycle);
|
||
|
|
||
|
EnableWindow(GetDlgItem(hDlg, DLG_SETUP_SMOOTH),
|
||
|
gflConfigOpt[Type] & OPT_SMOOTH_SHADE );
|
||
|
EnableWindow(GetDlgItem(hDlg, DLG_SETUP_CYCLE),
|
||
|
gflConfigOpt[Type] & OPT_COLOR_CYCLE );
|
||
|
|
||
|
EnableWindow(GetDlgItem(hDlg, DLG_SETUP_TESSEL),
|
||
|
gflConfigOpt[Type] & OPT_TESSEL);
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TESS),
|
||
|
gflConfigOpt[Type] & OPT_TESSEL);
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TESS_MIN),
|
||
|
gflConfigOpt[Type] & OPT_TESSEL);
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_STATIC_TESS_MAX),
|
||
|
gflConfigOpt[Type] & OPT_TESSEL);
|
||
|
|
||
|
EnableWindow(GetDlgItem(hDlg, DLG_SETUP_SIZE),
|
||
|
gflConfigOpt[Type] & OPT_SIZE);
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_STATIC_SIZE),
|
||
|
gflConfigOpt[Type] & OPT_SIZE);
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_STATIC_SIZE_MIN),
|
||
|
gflConfigOpt[Type] & OPT_SIZE);
|
||
|
EnableWindow(GetDlgItem(hDlg, IDC_STATIC_SIZE_MAX),
|
||
|
gflConfigOpt[Type] & OPT_SIZE);
|
||
|
|
||
|
EnableWindow(GetDlgItem(hDlg, DLG_SETUP_TEXTURE),
|
||
|
gflConfigOpt[Type] & OPT_TEXTURE);
|
||
|
}
|
||
|
|
||
|
/******************************Public*Routine******************************\
|
||
|
*
|
||
|
* ScreenSaverConfigureDialog
|
||
|
*
|
||
|
* Standard screensaver hook
|
||
|
*
|
||
|
* History:
|
||
|
* Wed Jul 19 14:56:41 1995 -by- Drew Bliss [drewb]
|
||
|
* Created
|
||
|
*
|
||
|
\**************************************************************************/
|
||
|
BOOL CALLBACK CFlyingObjectsScreensaver::ScreenSaverConfigureDialog(HWND hDlg, UINT message,
|
||
|
WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
int wTmp;
|
||
|
TCHAR szString[GEN_STRING_SIZE];
|
||
|
|
||
|
switch (message) {
|
||
|
case WM_INITDIALOG:
|
||
|
g_pMyFlyingObjectsScreensaver->ReadSettings();
|
||
|
|
||
|
setupDialogControls(hDlg);
|
||
|
|
||
|
for (wTmp = 0; wTmp <= MAX_TYPE; wTmp++) {
|
||
|
LoadString(NULL, idsStyles[wTmp], szString, GEN_STRING_SIZE);
|
||
|
SendDlgItemMessage(hDlg, DLG_SETUP_TYPES, CB_ADDSTRING, 0,
|
||
|
(LPARAM) szString);
|
||
|
}
|
||
|
SendDlgItemMessage(hDlg, DLG_SETUP_TYPES, CB_SETCURSEL, Type, 0);
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
switch (LOWORD(wParam)) {
|
||
|
case DLG_SETUP_TYPES:
|
||
|
switch (HIWORD(wParam))
|
||
|
{
|
||
|
case CBN_EDITCHANGE:
|
||
|
case CBN_SELCHANGE:
|
||
|
Type = (int)SendDlgItemMessage(hDlg, DLG_SETUP_TYPES,
|
||
|
CB_GETCURSEL, 0, 0);
|
||
|
updateDialogControls(hDlg);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return FALSE;
|
||
|
|
||
|
case DLG_SETUP_TEXTURE:
|
||
|
ss_SelectTextureFile( hDlg, &gTexFile );
|
||
|
break;
|
||
|
|
||
|
case DLG_SETUP_MONITORSETTINGS:
|
||
|
g_pMyFlyingObjectsScreensaver->DoScreenSettingsDialog( hDlg );
|
||
|
break;
|
||
|
|
||
|
case IDOK:
|
||
|
g_pMyFlyingObjectsScreensaver->WriteSettings( hDlg );
|
||
|
EndDialog(hDlg, TRUE);
|
||
|
break;
|
||
|
|
||
|
case IDCANCEL:
|
||
|
EndDialog(hDlg, FALSE);
|
||
|
break;
|
||
|
|
||
|
case DLG_SETUP_SMOOTH:
|
||
|
case DLG_SETUP_CYCLE:
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return TRUE;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return 0;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: WinMain()
|
||
|
// Desc: Entry point to the program. Initializes everything, and goes into a
|
||
|
// message-processing loop. Idle time is used to render the scene.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
CFlyingObjectsScreensaver flyingobjectsSS;
|
||
|
|
||
|
if( FAILED( hr = flyingobjectsSS.Create( hInst ) ) )
|
||
|
{
|
||
|
flyingobjectsSS.DisplayErrorMsg( hr );
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return flyingobjectsSS.Run();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: CFlyingObjectsScreensaver()
|
||
|
// Desc: Constructor
|
||
|
//-----------------------------------------------------------------------------
|
||
|
CFlyingObjectsScreensaver::CFlyingObjectsScreensaver( )
|
||
|
{
|
||
|
g_pMyFlyingObjectsScreensaver = this;
|
||
|
g_pFloatRect = &m_floatrect;
|
||
|
|
||
|
ZeroMemory( m_DeviceObjectsArray, sizeof(m_DeviceObjectsArray) );
|
||
|
m_pDeviceObjects = NULL;
|
||
|
|
||
|
LoadString( NULL, IDS_DESCRIPTION, m_strWindowTitle, 200 );
|
||
|
m_bUseDepthBuffer = TRUE;
|
||
|
|
||
|
lstrcpy( m_strRegPath, TEXT("Software\\Microsoft\\Screensavers\\Flying Objects") );
|
||
|
|
||
|
m_floatrect.xSize = 0.0f;
|
||
|
InitCommonControls();
|
||
|
|
||
|
bSmoothShading = FALSE;
|
||
|
bColorCycle = FALSE;
|
||
|
UpdateFlags = (bColorCycle << 1);
|
||
|
Type = 0;
|
||
|
fTesselFact = 2.0f;
|
||
|
uSize = 50;
|
||
|
ss_GetDefaultBmpFile( gTexFile.szPathName );
|
||
|
gTexFile.nOffset = 0;
|
||
|
|
||
|
ss_LoadTextureResourceStrings();
|
||
|
|
||
|
srand((UINT)time(NULL)); // seed random number generator
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: RegisterSoftwareDevice()
|
||
|
// Desc: This can register the D3D8RGBRasterizer or any other
|
||
|
// pluggable software rasterizer.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
HRESULT CFlyingObjectsScreensaver::RegisterSoftwareDevice()
|
||
|
{
|
||
|
m_pD3D->RegisterSoftwareDevice( D3D8RGBRasterizer );
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: SetMaterialColor()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
HRESULT CFlyingObjectsScreensaver::SetMaterialColor(FLOAT* pfColors)
|
||
|
{
|
||
|
D3DMATERIAL8 mtrl;
|
||
|
ZeroMemory( &mtrl, sizeof(mtrl) );
|
||
|
mtrl.Diffuse.r = mtrl.Ambient.r = pfColors[0];
|
||
|
mtrl.Diffuse.g = mtrl.Ambient.g = pfColors[1];
|
||
|
mtrl.Diffuse.b = mtrl.Ambient.b = pfColors[2];
|
||
|
mtrl.Diffuse.a = mtrl.Ambient.a = pfColors[3];
|
||
|
mtrl.Specular.r = 1.0f;
|
||
|
mtrl.Specular.g = 1.0f;
|
||
|
mtrl.Specular.b = 1.0f;
|
||
|
mtrl.Specular.a = 1.0f;
|
||
|
mtrl.Power = 30.0f;
|
||
|
|
||
|
return m_pd3dDevice->SetMaterial(&mtrl);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: FrameMove()
|
||
|
// Desc: Called once per frame, the call is the entry point for animating
|
||
|
// the scene.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
HRESULT CFlyingObjectsScreensaver::FrameMove()
|
||
|
{
|
||
|
// update floatrect
|
||
|
RECT rcBounceBounds;
|
||
|
|
||
|
if( m_floatrect.xSize == 0.0f )
|
||
|
{
|
||
|
// Initialize floatrect
|
||
|
RECT rcBounds;
|
||
|
DWORD dwParentWidth;
|
||
|
DWORD dwParentHeight;
|
||
|
|
||
|
rcBounds = m_rcRenderTotal;
|
||
|
|
||
|
dwParentWidth = rcBounds.right - rcBounds.left;
|
||
|
dwParentHeight = rcBounds.bottom - rcBounds.top;
|
||
|
|
||
|
FLOAT sizeFact;
|
||
|
FLOAT sizeScale;
|
||
|
DWORD size;
|
||
|
|
||
|
sizeScale = (FLOAT)uSize / 150.0f;
|
||
|
|
||
|
// sizeFact = 0.25f + (0.5f * sizeScale); // range 25-75%
|
||
|
// size = (DWORD) (sizeFact * ( ((FLOAT)(dwParentWidth + dwParentHeight)) / 2.0f ));
|
||
|
|
||
|
// sizeFact = 0.25f + (0.75f * sizeScale); // range 25-100%
|
||
|
// Note: there are bouncing problems when size is 100% (gbBounce is always
|
||
|
// true) -- things "jitter" too much. So limit size to 95% for this screensaver.
|
||
|
sizeFact = 0.25f + (0.70f * sizeScale); // range 25-95%
|
||
|
size = (DWORD) (sizeFact * ( dwParentWidth > dwParentHeight ? dwParentHeight : dwParentWidth ) );
|
||
|
|
||
|
if( size > dwParentWidth )
|
||
|
size = dwParentWidth;
|
||
|
if( size > dwParentHeight )
|
||
|
size = dwParentHeight;
|
||
|
|
||
|
// Start floatrect centered on first RenderUnit's screen
|
||
|
if( !m_bWindowed )
|
||
|
{
|
||
|
INT iMonitor = m_RenderUnits[0].iMonitor;
|
||
|
rcBounds = m_Monitors[iMonitor].rcScreen;
|
||
|
}
|
||
|
m_floatrect.xMin = rcBounds.left + ((rcBounds.right - rcBounds.left) - size) / 2.0f;
|
||
|
m_floatrect.yMin = rcBounds.top + ((rcBounds.bottom - rcBounds.top) - size) / 2.0f;
|
||
|
m_floatrect.xOrigin = m_floatrect.xMin;
|
||
|
m_floatrect.yOrigin = m_floatrect.yMin;
|
||
|
m_floatrect.xSize = (FLOAT)size;
|
||
|
m_floatrect.ySize = (FLOAT)size;
|
||
|
|
||
|
m_floatrect.xVel = 0.01f * (FLOAT) size;
|
||
|
if( rand() % 2 == 0 )
|
||
|
m_floatrect.xVel = -m_floatrect.xVel;
|
||
|
|
||
|
m_floatrect.yVel = 0.01f * (FLOAT) size;
|
||
|
if( rand() % 2 == 0 )
|
||
|
m_floatrect.yVel = -m_floatrect.yVel;
|
||
|
|
||
|
m_floatrect.xVelMax = m_floatrect.xVel;
|
||
|
m_floatrect.yVelMax = m_floatrect.yVel;
|
||
|
}
|
||
|
|
||
|
rcBounceBounds = m_rcRenderTotal;
|
||
|
|
||
|
FLOAT xMinOld = m_floatrect.xMin;
|
||
|
FLOAT yMinOld = m_floatrect.yMin;
|
||
|
|
||
|
if( g_bMoveToOrigin )
|
||
|
{
|
||
|
if( m_floatrect.xVel < 0 && m_floatrect.xMin < m_floatrect.xOrigin ||
|
||
|
m_floatrect.xVel > 0 && m_floatrect.xMin > m_floatrect.xOrigin )
|
||
|
{
|
||
|
m_floatrect.xVel = -m_floatrect.xVel;
|
||
|
}
|
||
|
if( m_floatrect.yVel < 0 && m_floatrect.yMin < m_floatrect.yOrigin ||
|
||
|
m_floatrect.yVel > 0 && m_floatrect.yMin > m_floatrect.yOrigin )
|
||
|
{
|
||
|
m_floatrect.yVel = -m_floatrect.yVel;
|
||
|
}
|
||
|
m_floatrect.xMin += m_floatrect.xVel * 20.0f * m_fElapsedTime;
|
||
|
m_floatrect.yMin += m_floatrect.yVel * 20.0f * m_fElapsedTime;
|
||
|
|
||
|
if( m_floatrect.xVel < 0 && m_floatrect.xMin < m_floatrect.xOrigin ||
|
||
|
m_floatrect.xVel > 0 && m_floatrect.xMin > m_floatrect.xOrigin )
|
||
|
{
|
||
|
m_floatrect.xMin = m_floatrect.xOrigin;
|
||
|
m_floatrect.xVel = 0.0f;
|
||
|
}
|
||
|
if( m_floatrect.yVel < 0 && m_floatrect.yMin < m_floatrect.yOrigin ||
|
||
|
m_floatrect.yVel > 0 && m_floatrect.yMin > m_floatrect.yOrigin )
|
||
|
{
|
||
|
m_floatrect.yMin = m_floatrect.yOrigin;
|
||
|
m_floatrect.yVel = 0.0f;
|
||
|
}
|
||
|
if( m_floatrect.xMin == m_floatrect.xOrigin &&
|
||
|
m_floatrect.yMin == m_floatrect.yOrigin )
|
||
|
{
|
||
|
g_bAtOrigin = TRUE;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
g_bAtOrigin = FALSE;
|
||
|
if( m_floatrect.xVel == 0.0f )
|
||
|
{
|
||
|
m_floatrect.xVel = m_floatrect.xVelMax;
|
||
|
if( rand() % 2 == 0 )
|
||
|
m_floatrect.xVel = -m_floatrect.xVel;
|
||
|
}
|
||
|
if( m_floatrect.yVel == 0.0f )
|
||
|
{
|
||
|
m_floatrect.yVel = m_floatrect.yVelMax;
|
||
|
if( rand() % 2 == 0 )
|
||
|
m_floatrect.yVel = -m_floatrect.yVel;
|
||
|
}
|
||
|
|
||
|
m_floatrect.xMin += m_floatrect.xVel * 20.0f * m_fElapsedTime;
|
||
|
m_floatrect.yMin += m_floatrect.yVel * 20.0f * m_fElapsedTime;
|
||
|
if( m_floatrect.xVel < 0 && m_floatrect.xMin < rcBounceBounds.left ||
|
||
|
m_floatrect.xVel > 0 && (m_floatrect.xMin + m_floatrect.xSize) > rcBounceBounds.right )
|
||
|
{
|
||
|
gbBounce = TRUE;
|
||
|
m_floatrect.xMin = xMinOld; // undo last move
|
||
|
m_floatrect.xVel = -m_floatrect.xVel; // change direction
|
||
|
}
|
||
|
if( m_floatrect.yVel < 0 && m_floatrect.yMin < rcBounceBounds.top ||
|
||
|
m_floatrect.yVel > 0 && (m_floatrect.yMin + m_floatrect.ySize) > rcBounceBounds.bottom )
|
||
|
{
|
||
|
gbBounce = TRUE;
|
||
|
m_floatrect.yMin = yMinOld; // undo last move
|
||
|
m_floatrect.yVel = -m_floatrect.yVel; // change direction
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID SetProjectionMatrixInfo( BOOL bOrtho, FLOAT fWidth,
|
||
|
FLOAT fHeight, FLOAT fNear, FLOAT fFar )
|
||
|
{
|
||
|
g_pMyFlyingObjectsScreensaver->m_bOrtho = bOrtho;
|
||
|
g_pMyFlyingObjectsScreensaver->m_fWidth = fWidth;
|
||
|
g_pMyFlyingObjectsScreensaver->m_fHeight = fHeight;
|
||
|
g_pMyFlyingObjectsScreensaver->m_fNear = fNear;
|
||
|
g_pMyFlyingObjectsScreensaver->m_fFar = fFar;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: Render()
|
||
|
// Desc: Called once per frame, the call is the entry point for 3d
|
||
|
// rendering. This function sets up render states, clears the
|
||
|
// viewport, and renders the scene.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
HRESULT CFlyingObjectsScreensaver::Render()
|
||
|
{
|
||
|
D3DVIEWPORT8 vp;
|
||
|
|
||
|
// First, clear the entire back buffer to the background color
|
||
|
vp.X = 0;
|
||
|
vp.Y = 0;
|
||
|
vp.Width = m_rcRenderCurDevice.right - m_rcRenderCurDevice.left;
|
||
|
vp.Height = m_rcRenderCurDevice.bottom - m_rcRenderCurDevice.top;
|
||
|
vp.MinZ = 0.0f;
|
||
|
vp.MaxZ = 1.0f;
|
||
|
m_pd3dDevice->SetViewport( &vp );
|
||
|
m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0L );
|
||
|
|
||
|
// Now determine what part of the floatrect, if any, intersects the current screen
|
||
|
RECT rcFloatThisScreen;
|
||
|
RECT rcFloatThisScreenClipped;
|
||
|
|
||
|
rcFloatThisScreen.left = (INT)m_floatrect.xMin;
|
||
|
rcFloatThisScreen.top = (INT)m_floatrect.yMin;
|
||
|
rcFloatThisScreen.right = rcFloatThisScreen.left + (INT)m_floatrect.xSize;
|
||
|
rcFloatThisScreen.bottom = rcFloatThisScreen.top + (INT)m_floatrect.ySize;
|
||
|
|
||
|
if( !IntersectRect(&rcFloatThisScreenClipped, &rcFloatThisScreen, &m_rcRenderCurDevice) )
|
||
|
{
|
||
|
return S_OK; // no intersection, so nothing further to render on this screen
|
||
|
}
|
||
|
|
||
|
// Convert rcFloatThisScreen from screen to window coordinates
|
||
|
OffsetRect(&rcFloatThisScreen, -m_rcRenderCurDevice.left, -m_rcRenderCurDevice.top);
|
||
|
OffsetRect(&rcFloatThisScreenClipped, -m_rcRenderCurDevice.left, -m_rcRenderCurDevice.top);
|
||
|
|
||
|
// Now set up the viewport to render to the clipped rect
|
||
|
vp.X = rcFloatThisScreenClipped.left;
|
||
|
vp.Y = rcFloatThisScreenClipped.top;
|
||
|
vp.Width = rcFloatThisScreenClipped.right - rcFloatThisScreenClipped.left;
|
||
|
vp.Height = rcFloatThisScreenClipped.bottom - rcFloatThisScreenClipped.top;
|
||
|
vp.MinZ = 0.0f;
|
||
|
vp.MaxZ = 1.0f;
|
||
|
m_pd3dDevice->SetViewport( &vp );
|
||
|
// m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000080, 1.0f, 0L );
|
||
|
|
||
|
// Now set up the projection matrix to only render the onscreen part of the
|
||
|
// rect to the viewport
|
||
|
D3DXMATRIX matProj;
|
||
|
FLOAT l,r,b,t;
|
||
|
l = -m_fWidth / 2;
|
||
|
r = m_fWidth / 2;
|
||
|
b = -m_fHeight / 2;
|
||
|
t = m_fHeight / 2;
|
||
|
FLOAT cxUnclipped = (rcFloatThisScreen.right + rcFloatThisScreen.left) / 2.0f;
|
||
|
FLOAT cyUnclipped = (rcFloatThisScreen.bottom + rcFloatThisScreen.top) / 2.0f;
|
||
|
l *= (rcFloatThisScreenClipped.left - cxUnclipped) / (rcFloatThisScreen.left - cxUnclipped);
|
||
|
r *= (rcFloatThisScreenClipped.right - cxUnclipped) / (rcFloatThisScreen.right - cxUnclipped);
|
||
|
t *= (rcFloatThisScreenClipped.top - cyUnclipped) / (rcFloatThisScreen.top - cyUnclipped);
|
||
|
b *= (rcFloatThisScreenClipped.bottom - cyUnclipped) / (rcFloatThisScreen.bottom - cyUnclipped);
|
||
|
if( m_bOrtho )
|
||
|
{
|
||
|
D3DXMatrixOrthoOffCenterLH( &matProj, l, r, b, t, m_fNear, m_fFar );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
D3DXMatrixPerspectiveOffCenterLH( &matProj, l, r, b, t, m_fNear, m_fFar );
|
||
|
}
|
||
|
m_pd3dDevice->SetTransform( D3DTS_PROJECTION , &matProj );
|
||
|
|
||
|
// Make elapsed time be zero unless time has really advanced since
|
||
|
// the last call, so things don't move faster in multimon situations.
|
||
|
// The right way to do this would be to separate the animation code from
|
||
|
// the rendering code.
|
||
|
FLOAT fElapsedTime;
|
||
|
static FLOAT s_fTimeLast = 0.0f;
|
||
|
if( m_fTime == s_fTimeLast )
|
||
|
fElapsedTime = 0.0f;
|
||
|
else
|
||
|
fElapsedTime = m_fElapsedTime;
|
||
|
s_fTimeLast = m_fTime;
|
||
|
|
||
|
// Begin the scene
|
||
|
if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
|
||
|
{
|
||
|
::m_pd3dDevice = m_pd3dDevice;
|
||
|
::m_pIB = m_pDeviceObjects->m_pIB;
|
||
|
::m_pVB = m_pDeviceObjects->m_pVB;
|
||
|
::m_pVB2 = m_pDeviceObjects->m_pVB2;
|
||
|
|
||
|
updateSceneFunc( UpdateFlags, fElapsedTime );
|
||
|
|
||
|
// End the scene.
|
||
|
m_pd3dDevice->EndScene();
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: SetDevice()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
VOID CFlyingObjectsScreensaver::SetDevice( UINT iDevice )
|
||
|
{
|
||
|
m_pDeviceObjects = &m_DeviceObjectsArray[iDevice];
|
||
|
g_pDeviceObjects = m_pDeviceObjects;
|
||
|
|
||
|
INT iMonitor = m_RenderUnits[iDevice].iMonitor;
|
||
|
g_xScreenOrigin = m_Monitors[iMonitor].rcScreen.left;
|
||
|
g_yScreenOrigin = m_Monitors[iMonitor].rcScreen.top;
|
||
|
g_iDevice = iDevice;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: LoadTextureFromResource()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
HRESULT LoadTextureFromResource( LPDIRECT3DDEVICE8 pd3dDevice,
|
||
|
TCHAR* strRes, TCHAR* strResType, LPDIRECT3DTEXTURE8* ppTex )
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
HMODULE hModule = NULL;
|
||
|
HRSRC rsrc;
|
||
|
HGLOBAL hgData;
|
||
|
LPVOID pvData;
|
||
|
DWORD cbData;
|
||
|
|
||
|
rsrc = FindResource( hModule, strRes, strResType );
|
||
|
if( rsrc != NULL )
|
||
|
{
|
||
|
cbData = SizeofResource( hModule, rsrc );
|
||
|
if( cbData > 0 )
|
||
|
{
|
||
|
hgData = LoadResource( hModule, rsrc );
|
||
|
if( hgData != NULL )
|
||
|
{
|
||
|
pvData = LockResource( hgData );
|
||
|
if( pvData != NULL )
|
||
|
{
|
||
|
if( FAILED( hr = D3DXCreateTextureFromFileInMemory( pd3dDevice,
|
||
|
pvData, cbData, ppTex ) ) )
|
||
|
{
|
||
|
return hr;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( *ppTex == NULL)
|
||
|
return E_FAIL;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: RestoreDeviceObjects()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
HRESULT CFlyingObjectsScreensaver::RestoreDeviceObjects()
|
||
|
{
|
||
|
if( m_pd3dDevice == NULL )
|
||
|
return S_OK;
|
||
|
|
||
|
::m_pd3dDevice = m_pd3dDevice;
|
||
|
|
||
|
|
||
|
/*
|
||
|
D3DLIGHT8 light;
|
||
|
D3DUtil_InitLight( light, D3DLIGHT_POINT, 2.0, 2.0, 10.0 );
|
||
|
light.Specular.r = 1.0f;
|
||
|
light.Specular.g = 1.0f;
|
||
|
light.Specular.b = 1.0f;
|
||
|
light.Specular.a = 1.0f;
|
||
|
light.Attenuation0 = 1.0f;
|
||
|
m_pd3dDevice->SetLight(0, &light);
|
||
|
m_pd3dDevice->LightEnable(0, TRUE);
|
||
|
*/
|
||
|
|
||
|
// Set some basic renderstates
|
||
|
m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE , TRUE );
|
||
|
m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE , TRUE );
|
||
|
m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR(0x20202020) );
|
||
|
/* if( config.two_sided == GL_FRONT_AND_BACK )
|
||
|
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
|
||
|
else
|
||
|
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
|
||
|
*/
|
||
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLOROP , D3DTOP_SELECTARG1 );
|
||
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG1 , D3DTA_DIFFUSE );
|
||
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE );
|
||
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ALPHAOP , D3DTOP_DISABLE );
|
||
|
m_pd3dDevice->SetTextureStageState( 1 , D3DTSS_COLOROP , D3DTOP_DISABLE );
|
||
|
m_pd3dDevice->SetTextureStageState( 1 , D3DTSS_ALPHAOP , D3DTOP_DISABLE );
|
||
|
|
||
|
|
||
|
D3DMATERIAL8 mtrl;
|
||
|
ZeroMemory( &mtrl, sizeof(mtrl) );
|
||
|
mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
|
||
|
mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
|
||
|
mtrl.Diffuse.b = mtrl.Ambient.b = 1.0f;
|
||
|
mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
|
||
|
|
||
|
m_pd3dDevice->SetMaterial(&mtrl);
|
||
|
|
||
|
if( !_3dfo_Init(NULL) )
|
||
|
return E_FAIL;
|
||
|
|
||
|
if( Type == 6 )
|
||
|
{
|
||
|
if( FAILED( D3DXCreateTextureFromFile( m_pd3dDevice, gTexFile.szPathName,
|
||
|
&m_pDeviceObjects->m_pTexture ) ) )
|
||
|
{
|
||
|
LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDB_DEFTEX), TEXT("JPG"),
|
||
|
&m_pDeviceObjects->m_pTexture );
|
||
|
}
|
||
|
}
|
||
|
else if( Type == 0 )
|
||
|
{
|
||
|
LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDR_FLATFLAG), TEXT("DDS"),
|
||
|
&m_pDeviceObjects->m_pTexture );
|
||
|
LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDR_WINLOGO), TEXT("PNG"),
|
||
|
&m_pDeviceObjects->m_pTexture2 );
|
||
|
}
|
||
|
|
||
|
m_pd3dDevice->SetTexture( 0, m_pDeviceObjects->m_pTexture );
|
||
|
|
||
|
if( FAILED( m_pd3dDevice->CreateIndexBuffer( MAX_INDICES * sizeof(WORD),
|
||
|
D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pDeviceObjects->m_pIB ) ) )
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
if( FAILED( m_pd3dDevice->CreateVertexBuffer( MAX_VERTICES * sizeof(MYVERTEX),
|
||
|
D3DUSAGE_WRITEONLY, D3DFVF_MYVERTEX, D3DPOOL_MANAGED, &m_pDeviceObjects->m_pVB ) ) )
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
if( FAILED( m_pd3dDevice->CreateVertexBuffer( MAX_VERTICES * sizeof(MYVERTEX2),
|
||
|
D3DUSAGE_WRITEONLY, D3DFVF_MYVERTEX2, D3DPOOL_MANAGED, &m_pDeviceObjects->m_pVB2 ) ) )
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: InvalidateDeviceObjects()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
HRESULT CFlyingObjectsScreensaver::InvalidateDeviceObjects()
|
||
|
{
|
||
|
SAFE_RELEASE( m_pDeviceObjects->m_pTexture );
|
||
|
SAFE_RELEASE( m_pDeviceObjects->m_pTexture2 );
|
||
|
SAFE_RELEASE( m_pDeviceObjects->m_pIB );
|
||
|
SAFE_RELEASE( m_pDeviceObjects->m_pVB );
|
||
|
SAFE_RELEASE( m_pDeviceObjects->m_pVB2 );
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: ReadSettings()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
VOID CFlyingObjectsScreensaver::ReadSettings()
|
||
|
{
|
||
|
int options;
|
||
|
int optMask = 1;
|
||
|
int tessel=0;
|
||
|
|
||
|
// Read OpenGL settings first, so OS upgrade cases work
|
||
|
ss_ReadSettings();
|
||
|
|
||
|
HKEY hkey;
|
||
|
|
||
|
if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, m_strRegPath,
|
||
|
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
|
||
|
{
|
||
|
options = bSmoothShading | bColorCycle<<1;
|
||
|
DXUtil_ReadIntRegKey( hkey, TEXT("Options"), (DWORD*)&options, options );
|
||
|
if (options >= 0)
|
||
|
{
|
||
|
bSmoothShading = ((options & optMask) != 0);
|
||
|
optMask <<= 1;
|
||
|
bColorCycle = ((options & optMask) != 0);
|
||
|
UpdateFlags = (bColorCycle << 1);
|
||
|
}
|
||
|
|
||
|
DXUtil_ReadIntRegKey( hkey, TEXT("Type"), (DWORD*)&Type, Type );
|
||
|
|
||
|
// Sanity check Type. Don't want to index into function arrays
|
||
|
// with a bad index!
|
||
|
Type = (int)min(Type, MAX_TYPE);
|
||
|
|
||
|
// Set flag so that updateStripScene will do two strips instead
|
||
|
// of one.
|
||
|
|
||
|
if (Type == 3)
|
||
|
UpdateFlags |= 0x4;
|
||
|
|
||
|
tessel = (int) (fTesselFact * 100);
|
||
|
DXUtil_ReadIntRegKey( hkey, TEXT("Tesselation"), (DWORD*)&tessel, tessel );
|
||
|
SS_CLAMP_TO_RANGE2( tessel, 0, 200 );
|
||
|
|
||
|
if (tessel <= 100)
|
||
|
fTesselFact = (float)tessel / 100.0f;
|
||
|
else
|
||
|
fTesselFact = 1.0f + (((float)tessel - 100.0f) / 100.0f);
|
||
|
|
||
|
DXUtil_ReadIntRegKey( hkey, TEXT("Size"), (DWORD*)&uSize, uSize );
|
||
|
if (uSize > 100)
|
||
|
uSize = 100;
|
||
|
|
||
|
// Static size for new winlogo
|
||
|
if (Type == 0)
|
||
|
{
|
||
|
uSize = 75;
|
||
|
bSmoothShading = TRUE;
|
||
|
}
|
||
|
|
||
|
// SS_CLAMP_TO_RANGE2( uSize, 0, 100 ); /* can't be less than zero since it is a UINT */
|
||
|
|
||
|
// Is there a texture specified in the registry that overrides the
|
||
|
// default?
|
||
|
|
||
|
DXUtil_ReadStringRegKey( hkey, TEXT("Texture"), (TCHAR*)&gTexFile.szPathName,
|
||
|
MAX_PATH, gTexFile.szPathName );
|
||
|
|
||
|
DXUtil_ReadIntRegKey( hkey, TEXT("TextureFileOffset"), (DWORD*)&gTexFile.nOffset, gTexFile.nOffset );
|
||
|
|
||
|
ReadScreenSettings( hkey );
|
||
|
|
||
|
RegCloseKey( hkey );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: ss_ReadSettings()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
VOID CFlyingObjectsScreensaver::ss_ReadSettings()
|
||
|
{
|
||
|
int options;
|
||
|
int optMask = 1;
|
||
|
TCHAR szDefaultBitmap[MAX_PATH];
|
||
|
int tessel=0;
|
||
|
|
||
|
if( ss_RegistrySetup( IDS_SAVERNAME, IDS_INIFILE ) )
|
||
|
{
|
||
|
options = ss_GetRegistryInt( IDS_OPTIONS, -1 );
|
||
|
if (options >= 0)
|
||
|
{
|
||
|
bSmoothShading = ((options & optMask) != 0);
|
||
|
optMask <<= 1;
|
||
|
bColorCycle = ((options & optMask) != 0);
|
||
|
UpdateFlags = (bColorCycle << 1);
|
||
|
}
|
||
|
|
||
|
Type = ss_GetRegistryInt( IDS_OBJTYPE, 0 );
|
||
|
|
||
|
// Sanity check Type. Don't want to index into function arrays
|
||
|
// with a bad index!
|
||
|
Type = (int)min(Type, MAX_TYPE);
|
||
|
|
||
|
// Set flag so that updateStripScene will do two strips instead
|
||
|
// of one.
|
||
|
|
||
|
if (Type == 3)
|
||
|
UpdateFlags |= 0x4;
|
||
|
|
||
|
tessel = ss_GetRegistryInt( IDS_TESSELATION, 100 );
|
||
|
SS_CLAMP_TO_RANGE2( tessel, 0, 200 );
|
||
|
|
||
|
if (tessel <= 100)
|
||
|
fTesselFact = (float)tessel / 100.0f;
|
||
|
else
|
||
|
fTesselFact = 1.0f + (((float)tessel - 100.0f) / 100.0f);
|
||
|
|
||
|
uSize = ss_GetRegistryInt( IDS_SIZE, 50 );
|
||
|
if (uSize > 100)
|
||
|
uSize = 100;
|
||
|
// SS_CLAMP_TO_RANGE2( uSize, 0, 100 ); /* can't be less than zero since it is a UINT */
|
||
|
|
||
|
// Determine the default .bmp file
|
||
|
|
||
|
ss_GetDefaultBmpFile( szDefaultBitmap );
|
||
|
|
||
|
// Is there a texture specified in the registry that overrides the
|
||
|
// default?
|
||
|
|
||
|
|
||
|
ss_GetRegistryString( IDS_TEXTURE, szDefaultBitmap, gTexFile.szPathName,
|
||
|
MAX_PATH);
|
||
|
|
||
|
gTexFile.nOffset = ss_GetRegistryInt( IDS_TEXTURE_FILE_OFFSET, 0 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: ss_GetRegistryString()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
BOOL CFlyingObjectsScreensaver::ss_RegistrySetup( int section, int file )
|
||
|
{
|
||
|
if( LoadString(m_hInstance, section, g_szSectName, BUF_SIZE) &&
|
||
|
LoadString(m_hInstance, file, g_szFname, BUF_SIZE) )
|
||
|
{
|
||
|
TCHAR pBuffer[100];
|
||
|
DWORD dwRealSize = GetPrivateProfileSection( g_szSectName, pBuffer, 100, g_szFname );
|
||
|
if( dwRealSize > 0 )
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: ss_GetRegistryString()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int CFlyingObjectsScreensaver::ss_GetRegistryInt( int name, int iDefault )
|
||
|
{
|
||
|
TCHAR szItemName[BUF_SIZE];
|
||
|
|
||
|
if( LoadString( m_hInstance, name, szItemName, BUF_SIZE ) )
|
||
|
return GetPrivateProfileInt(g_szSectName, szItemName, iDefault, g_szFname);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: ss_GetRegistryString()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
VOID CFlyingObjectsScreensaver::ss_GetRegistryString( int name, LPTSTR lpDefault,
|
||
|
LPTSTR lpDest, int bufSize )
|
||
|
{
|
||
|
TCHAR szItemName[BUF_SIZE];
|
||
|
|
||
|
if( LoadString( m_hInstance, name, szItemName, BUF_SIZE ) )
|
||
|
GetPrivateProfileString(g_szSectName, szItemName, lpDefault, lpDest,
|
||
|
bufSize, g_szFname);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: DoConfig()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
VOID CFlyingObjectsScreensaver::DoConfig()
|
||
|
{
|
||
|
if( IDOK == DialogBox( NULL, MAKEINTRESOURCE( DLG_SCRNSAVECONFIGURE ),
|
||
|
m_hWndParent, (DLGPROC)ScreenSaverConfigureDialog ) )
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Name: ConfirmDevice()
|
||
|
// Desc:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
HRESULT CFlyingObjectsScreensaver::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior,
|
||
|
D3DFORMAT fmtBackBuffer)
|
||
|
{
|
||
|
if( dwBehavior & D3DCREATE_PUREDEVICE )
|
||
|
return E_FAIL;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|