631 lines
18 KiB
C
631 lines
18 KiB
C
/******************************Module*Header*******************************\
|
|
* Module Name: ss3dfo.c
|
|
*
|
|
* Dispatcher and dialog box for the OpenGL-based 3D Flying Objects screen
|
|
* saver.
|
|
*
|
|
* Created: 18-May-1994 14:54:59
|
|
*
|
|
* Copyright (c) 1994 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include <scrnsave.h>
|
|
#include <GL\gl.h>
|
|
#include <math.h>
|
|
#include <memory.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <malloc.h>
|
|
#include <sys\timeb.h>
|
|
#include <time.h>
|
|
#include <commdlg.h>
|
|
#include <commctrl.h>
|
|
#include "ss3dfo.h"
|
|
|
|
//#define SS_DEBUG 1
|
|
|
|
// Global strings.
|
|
#define GEN_STRING_SIZE 64
|
|
|
|
static SSContext gssc;
|
|
BOOL gbBounce = FALSE; // floating window bounce off side
|
|
|
|
// Global message loop variables.
|
|
MATERIAL Material[16];
|
|
#ifdef MEMDEBUG
|
|
ULONG totalMem = 0;
|
|
#endif
|
|
|
|
// Global screen saver settings.
|
|
|
|
void (*updateSceneFunc)(int); // current screen saver update function
|
|
void (*delSceneFunc)(void); // current screen saver deletion function
|
|
BOOL bColorCycle = FALSE; // color cycling flag
|
|
BOOL bSmoothShading = TRUE; // smooth shading flag
|
|
UINT uSize = 100; // object size
|
|
float fTesselFact = 1.0f; // object tessalation
|
|
int UpdateFlags = 0; // extra data sent to update function
|
|
int Type = 0; // screen saver index (into function arrays)
|
|
|
|
// 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 GLfloat 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},
|
|
};
|
|
|
|
extern void updateStripScene(int);
|
|
extern void updateDropScene(int);
|
|
extern void updateLemScene(int);
|
|
extern void updateExplodeScene(int);
|
|
extern void updateWinScene(int);
|
|
extern void updateTexScene(int);
|
|
extern void initStripScene(void);
|
|
extern void initDropScene(void);
|
|
extern void initLemScene(void);
|
|
extern void initExplodeScene(void);
|
|
extern void initWinScene(void);
|
|
extern void initTexScene(void);
|
|
extern void delStripScene(void);
|
|
extern void delDropScene(void);
|
|
extern void delLemScene(void);
|
|
extern void delExplodeScene(void);
|
|
extern void delWinScene(void);
|
|
extern void delTexScene(void);
|
|
|
|
typedef void (*PTRUPDATE)(int);
|
|
typedef void (*ptrdel)();
|
|
typedef void (*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, updateExplodeScene,updateStripScene, updateStripScene,
|
|
updateDropScene, updateLemScene, updateTexScene};
|
|
static ptrdel delFuncs[] =
|
|
{delWinScene, delExplodeScene, delStripScene, delStripScene,
|
|
delDropScene, delLemScene, delTexScene};
|
|
static ptrinit initFuncs[] =
|
|
{initWinScene, 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
|
|
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);
|
|
|
|
#ifdef MEMDEBUG
|
|
void xprintf(char *str, ...)
|
|
{
|
|
va_list ap;
|
|
char buffer[256];
|
|
|
|
va_start(ap, str);
|
|
vsprintf(buffer, str, ap);
|
|
|
|
OutputDebugString(buffer);
|
|
va_end(ap);
|
|
}
|
|
#endif
|
|
|
|
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);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* getIniSettings
|
|
*
|
|
* Get the screen saver configuration options from .INI file/registry.
|
|
*
|
|
* History:
|
|
* 10-May-1994 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
static void getIniSettings()
|
|
{
|
|
int options;
|
|
int optMask = 1;
|
|
TCHAR szDefaultBitmap[MAX_PATH];
|
|
int tessel=0;
|
|
LPTSTR psz;
|
|
|
|
LoadString(hMainInstance, IDS_GENNAME, szScreenSaver, sizeof(szScreenSaver) / sizeof(TCHAR));
|
|
|
|
if( ss_RegistrySetup( hMainInstance, 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 = 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 );
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* saveIniSettings
|
|
*
|
|
* Save the screen saver configuration option to the .INI file/registry.
|
|
*
|
|
* History:
|
|
* 10-May-1994 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
static void saveIniSettings(HWND hDlg)
|
|
{
|
|
if( ss_RegistrySetup( hMainInstance, IDS_SAVERNAME, IDS_INIFILE ) )
|
|
{
|
|
int pos, options;
|
|
int optMask = 1;
|
|
|
|
bSmoothShading = IsDlgButtonChecked(hDlg, DLG_SETUP_SMOOTH);
|
|
bColorCycle = IsDlgButtonChecked(hDlg, DLG_SETUP_CYCLE);
|
|
options = bColorCycle;
|
|
options <<= 1;
|
|
options |= bSmoothShading;
|
|
ss_WriteRegistryInt( IDS_OPTIONS, options );
|
|
|
|
Type = (int)SendDlgItemMessage(hDlg, DLG_SETUP_TYPES, CB_GETCURSEL,
|
|
0, 0);
|
|
ss_WriteRegistryInt( IDS_OBJTYPE, Type );
|
|
|
|
pos = ss_GetTrackbarPos( hDlg, DLG_SETUP_TESSEL );
|
|
ss_WriteRegistryInt( IDS_TESSELATION, pos );
|
|
|
|
pos = ss_GetTrackbarPos( hDlg, DLG_SETUP_SIZE );
|
|
ss_WriteRegistryInt( IDS_SIZE, pos );
|
|
|
|
ss_WriteRegistryString( IDS_TEXTURE, gTexFile.szPathName );
|
|
ss_WriteRegistryInt( IDS_TEXTURE_FILE_OFFSET, gTexFile.nOffset );
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* setupDialogControls
|
|
*
|
|
* Setup the dialog controls initially.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
static void
|
|
setupDialogControls(HWND hDlg)
|
|
{
|
|
int pos;
|
|
|
|
InitCommonControls();
|
|
|
|
if ( gflConfigOpt[Type] & OPT_TESSEL )
|
|
{
|
|
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 );
|
|
}
|
|
|
|
if ( gflConfigOpt[Type] & OPT_SIZE )
|
|
{
|
|
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);
|
|
}
|
|
|
|
BOOL WINAPI RegisterDialogClasses(HANDLE hinst)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* ScreenSaverConfigureDialog
|
|
*
|
|
* Processes messages for the configuration dialog box.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL ScreenSaverConfigureDialog(HWND hDlg, UINT message,
|
|
WPARAM wParam, LPARAM lParam)
|
|
{
|
|
int wTmp;
|
|
TCHAR szString[GEN_STRING_SIZE];
|
|
|
|
switch (message) {
|
|
case WM_INITDIALOG:
|
|
getIniSettings();
|
|
|
|
setupDialogControls(hDlg);
|
|
|
|
for (wTmp = 0; wTmp <= MAX_TYPE; wTmp++) {
|
|
LoadString(hMainInstance, 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 IDOK:
|
|
saveIniSettings(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;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* SetFloaterInfo
|
|
*
|
|
* Set the size and motion of the floating window
|
|
* It stays square in shape
|
|
*
|
|
\**************************************************************************/
|
|
|
|
static void
|
|
SetFloaterInfo( ISIZE *pParentSize, CHILD_INFO *pChild )
|
|
{
|
|
float sizeFact;
|
|
float sizeScale;
|
|
int size;
|
|
ISIZE *pChildSize = &pChild->size;
|
|
MOTION_INFO *pMotion = &pChild->motionInfo;
|
|
|
|
sizeScale = (float)uSize / 100.0f; // 0..1
|
|
sizeFact = 0.25f + (0.30f * sizeScale);
|
|
size = (int) (sizeFact * ( ((float)(pParentSize->width + pParentSize->height)) / 2.0f ));
|
|
SS_CLAMP_TO_RANGE2( size, 0, pParentSize->width );
|
|
SS_CLAMP_TO_RANGE2( size, 0, pParentSize->height );
|
|
|
|
pChildSize->width = pChildSize->height = size;
|
|
|
|
// Floater motion
|
|
pMotion->posInc.x = .01f * (float) size;
|
|
if( pMotion->posInc.x < 1.0f )
|
|
pMotion->posInc.x = 1.0f;
|
|
pMotion->posInc.y = pMotion->posInc.x;
|
|
pMotion->posIncVary.x = .4f * pMotion->posInc.x;
|
|
pMotion->posIncVary.y = pMotion->posIncVary.x;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* initMaterial
|
|
*
|
|
* Initialize the material properties.
|
|
*
|
|
\**************************************************************************/
|
|
|
|
void initMaterial(int id, float r, float g, float b, float a)
|
|
{
|
|
Material[id].ka.r = r;
|
|
Material[id].ka.g = g;
|
|
Material[id].ka.b = b;
|
|
Material[id].ka.a = a;
|
|
|
|
Material[id].kd.r = r;
|
|
Material[id].kd.g = g;
|
|
Material[id].kd.b = b;
|
|
Material[id].kd.a = a;
|
|
|
|
Material[id].ks.r = 1.0f;
|
|
Material[id].ks.g = 1.0f;
|
|
Material[id].ks.b = 1.0f;
|
|
Material[id].ks.a = 1.0f;
|
|
|
|
Material[id].specExp = 128.0f;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* _3dfo_Init
|
|
*
|
|
\**************************************************************************/
|
|
|
|
static void
|
|
_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)
|
|
glShadeModel(GL_SMOOTH);
|
|
else
|
|
glShadeModel(GL_FLAT);
|
|
|
|
// Setup the OpenGL matrices.
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
// Setup the lighting.
|
|
|
|
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (GLfloat *) &lightAmbient);
|
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
|
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
|
|
glLightfv(GL_LIGHT0, GL_AMBIENT, (GLfloat *) &light0Ambient);
|
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, (GLfloat *) &light0Diffuse);
|
|
glLightfv(GL_LIGHT0, GL_SPECULAR, (GLfloat *) &light0Specular);
|
|
glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
|
|
glEnable(GL_LIGHTING);
|
|
glEnable(GL_LIGHT0);
|
|
|
|
// Setup the material properties.
|
|
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (GLfloat *) &Material[0].ks);
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, (GLfloat *) &Material[0].specExp);
|
|
|
|
// call specific objects init func
|
|
(*initFuncs[Type])();
|
|
updateSceneFunc = updateFuncs[Type];
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* _3dfo_Draw
|
|
*
|
|
\**************************************************************************/
|
|
|
|
static void
|
|
_3dfo_Draw(void *data)
|
|
{
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
(*updateSceneFunc)(UpdateFlags);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* _3dfo_FloaterBounce
|
|
*
|
|
\**************************************************************************/
|
|
|
|
static void
|
|
_3dfo_FloaterBounce(void *data)
|
|
{
|
|
gbBounce = TRUE;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* ss_Init
|
|
*
|
|
* Screen saver entry point. Pre-GL initialization
|
|
*
|
|
\**************************************************************************/
|
|
|
|
SSContext *
|
|
ss_Init(void)
|
|
{
|
|
getIniSettings();
|
|
|
|
// Make sure the selected texture file is OK.
|
|
|
|
if ( gflConfigOpt[Type] & OPT_TEXTURE )
|
|
{
|
|
// Verify texture file
|
|
ss_DisableTextureErrorMsgs();
|
|
ss_VerifyTextureFile( &gTexFile );
|
|
}
|
|
|
|
// set callbacks
|
|
|
|
ss_InitFunc( _3dfo_Init );
|
|
ss_UpdateFunc( _3dfo_Draw );
|
|
|
|
// set configuration info to return
|
|
|
|
gssc.bDoubleBuf = TRUE;
|
|
gssc.depthType = SS_DEPTH16;
|
|
|
|
gssc.bFloater = TRUE;
|
|
gssc.floaterInfo.bMotion = TRUE;
|
|
gssc.floaterInfo.ChildSizeFunc = SetFloaterInfo;
|
|
ss_FloaterBounceFunc( _3dfo_FloaterBounce );
|
|
|
|
return &gssc;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* ConfigInit
|
|
*
|
|
* Dialog box version of ss_Init. Used for setting up any gl drawing on the
|
|
* dialog.
|
|
*
|
|
\**************************************************************************/
|
|
BOOL
|
|
ss_ConfigInit( HWND hDlg )
|
|
{
|
|
return TRUE;
|
|
}
|
|
|