1374 lines
47 KiB
C++
1374 lines
47 KiB
C++
//-----------------------------------------------------------------------------
|
|
// File: Text3D.cpp
|
|
//
|
|
// Desc: Fun screen saver.
|
|
//
|
|
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
|
|
//-----------------------------------------------------------------------------
|
|
#include <Windows.h>
|
|
#include <d3d8.h>
|
|
#include <d3dx8.h>
|
|
#include <d3dsaver.h>
|
|
#include <d3d8rgbrast.h>
|
|
#include <time.h>
|
|
#include <commdlg.h>
|
|
#include <commctrl.h>
|
|
#include "Text3D.h"
|
|
#include "Resource.h"
|
|
#include "dxutil.h"
|
|
|
|
|
|
CTextScreensaver* g_pMyTextScreensaver = NULL;
|
|
|
|
|
|
|
|
#define BUF_SIZE 255
|
|
TCHAR g_szSectName[BUF_SIZE];
|
|
TCHAR g_szFname[BUF_SIZE];
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// 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;
|
|
CTextScreensaver textSS;
|
|
|
|
if( FAILED( hr = textSS.Create( hInst ) ) )
|
|
{
|
|
textSS.DisplayErrorMsg( hr );
|
|
return 0;
|
|
}
|
|
|
|
return textSS.Run();
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// 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: CTextScreensaver()
|
|
// Desc: Constructor
|
|
//-----------------------------------------------------------------------------
|
|
CTextScreensaver::CTextScreensaver()
|
|
{
|
|
g_pMyTextScreensaver = this;
|
|
|
|
LoadString( NULL, IDS_DESCRIPTION, m_strWindowTitle, 200 );
|
|
InitCommonControls();
|
|
|
|
ZeroMemory( m_DeviceObjects, sizeof(m_DeviceObjects) );
|
|
m_hFont = NULL;
|
|
m_bUseDepthBuffer = TRUE;
|
|
m_dwMinDepthBits = 16;
|
|
m_floatrect.xSize = 0.0f;
|
|
lstrcpy( m_strRegPath, TEXT("Software\\Microsoft\\Screensavers\\Text3D") );
|
|
|
|
m_fAngleX = 0.0f;
|
|
m_fAngleY = 0.0f;
|
|
m_fAngleZ = 0.0f;
|
|
|
|
m_dwMeshUpdateCounter = 0;
|
|
|
|
srand((UINT)time(NULL)); // seed random number generator
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: RegisterSoftwareDevice()
|
|
// Desc: This can register the D3D8RGBRasterizer or any other
|
|
// pluggable software rasterizer.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CTextScreensaver::RegisterSoftwareDevice()
|
|
{
|
|
m_pD3D->RegisterSoftwareDevice( D3D8RGBRasterizer );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: FrameMove()
|
|
// Desc: Called once per frame, the call is the entry point for animating
|
|
// the scene.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CTextScreensaver::FrameMove()
|
|
{
|
|
DWORD tick = GetTickCount();
|
|
DWORD elapsed = tick - m_dwLastTick;
|
|
m_dwLastTick = tick;
|
|
|
|
// 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 = m_dwSize / 10.0f;
|
|
sizeFact = 0.25f + (0.75f * sizeScale); // range 25-100%
|
|
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.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;
|
|
}
|
|
|
|
rcBounceBounds = m_rcRenderTotal;
|
|
|
|
FLOAT xMinOld = m_floatrect.xMin;
|
|
FLOAT yMinOld = m_floatrect.yMin;
|
|
|
|
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 )
|
|
{
|
|
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 )
|
|
{
|
|
m_floatrect.yMin = yMinOld; // undo last move
|
|
m_floatrect.yVel = -m_floatrect.yVel; // change direction
|
|
}
|
|
|
|
UpdateAngles( elapsed );
|
|
|
|
if ( m_bDisplayTime )
|
|
{
|
|
if ( UpdateTimeString( m_szDisplayString ) )
|
|
{
|
|
m_dwMeshUpdateCounter++; // provoke a mesh update at render tiem
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// 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 CTextScreensaver::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, 0xff0000ff, 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 = -0.8f;
|
|
r = 0.8f;
|
|
b = 0.8f;
|
|
t = -0.8f;
|
|
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);
|
|
D3DXMatrixPerspectiveOffCenterLH( &matProj, l, r, t, b, 1.0f, 50.0f );
|
|
m_pd3dDevice->SetTransform( D3DTS_PROJECTION , &matProj );
|
|
|
|
// Mesh updates happen in Render() instead of FrameMove() since they
|
|
// are per-device
|
|
if( m_pDeviceObjects->m_dwMeshUpdateCounter != m_dwMeshUpdateCounter )
|
|
{
|
|
BuildTextMesh( m_szDisplayString );
|
|
m_pDeviceObjects->m_dwMeshUpdateCounter = m_dwMeshUpdateCounter;
|
|
}
|
|
|
|
m_pd3dDevice->BeginScene();
|
|
|
|
// Set world matrix
|
|
D3DXMATRIX rotx,roty,rotz,trans,trans2;
|
|
D3DXMatrixTranslation( &trans , m_fTextOffsetX , m_fTextOffsetY , 0.25f );
|
|
D3DXMatrixRotationX( &rotx , m_fAngleX );
|
|
D3DXMatrixRotationY( &roty , m_fAngleY );
|
|
D3DXMatrixRotationZ( &rotz , m_fAngleZ );
|
|
D3DXMatrixTranslation( &trans2, 0, 0, 1.5f + (m_fTextMaxX - m_fTextMinX) );
|
|
m_matWorld = trans * rotx * roty * rotz * trans2;
|
|
m_pd3dDevice->SetTransform( D3DTS_WORLDMATRIX(0) , &m_matWorld );
|
|
|
|
// Set other per-frame states
|
|
SetPerFrameStates();
|
|
|
|
// Draw mesh
|
|
m_pDeviceObjects->m_pObject->DrawSubset( 0 );
|
|
|
|
m_pd3dDevice->EndScene();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: RestoreDeviceObjects()
|
|
// Desc:
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CTextScreensaver::RestoreDeviceObjects()
|
|
{
|
|
HRESULT rc;
|
|
|
|
// Set up sensible view matrix
|
|
D3DXMatrixLookAtLH( &m_matView , &D3DXVECTOR3(0,0,0) , &D3DXVECTOR3(0,0,1) , &D3DXVECTOR3(0,1,0) );
|
|
m_pd3dDevice->SetTransform( D3DTS_VIEW , &m_matView );
|
|
|
|
// Set some basic renderstates
|
|
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE , TRUE );
|
|
m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE , D3DZB_TRUE );
|
|
m_pd3dDevice->SetRenderState( D3DRS_ZFUNC , D3DCMP_LESSEQUAL );
|
|
m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE , TRUE );
|
|
m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE , m_bSpecular );
|
|
|
|
// Create the GDI font object
|
|
LONG h = m_Font.lfHeight;
|
|
m_Font.lfHeight = 100;
|
|
m_hFont = CreateFontIndirect( &m_Font );
|
|
m_Font.lfHeight = h;
|
|
if ( m_hFont == NULL )
|
|
return E_FAIL;
|
|
|
|
// Initialise time string
|
|
if ( m_bDisplayTime )
|
|
UpdateTimeString( m_szDisplayString );
|
|
|
|
// Make mesh for text string
|
|
if ( FAILED(rc = BuildTextMesh( m_szDisplayString )) )
|
|
return rc;
|
|
|
|
// Update offsets for mesh
|
|
m_fTextOffsetX = (m_fTextMinX + m_fTextMaxX) * -0.5f;
|
|
m_fTextOffsetY = (m_fTextMinY + m_fTextMaxY) * -0.5f;
|
|
|
|
// Load appropriate texture (if any)
|
|
switch ( m_SurfType )
|
|
{
|
|
case color:
|
|
m_pDeviceObjects->m_pTexture = NULL;
|
|
break;
|
|
|
|
case environment:
|
|
if ( m_bUseCustomEnvironment )
|
|
{
|
|
m_pDeviceObjects->m_pTexture = CreateTextureFromFile( m_szCustomEnvironment );
|
|
}
|
|
if ( m_pDeviceObjects->m_pTexture == NULL )
|
|
{
|
|
LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDB_SPHEREMAP),
|
|
TEXT("JPG"), &m_pDeviceObjects->m_pTexture );
|
|
}
|
|
break;
|
|
|
|
case texture:
|
|
if ( m_bUseCustomTexture )
|
|
{
|
|
m_pDeviceObjects->m_pTexture = CreateTextureFromFile( m_szCustomTexture );
|
|
}
|
|
if ( m_pDeviceObjects->m_pTexture == NULL )
|
|
{
|
|
LoadTextureFromResource( m_pd3dDevice, MAKEINTRESOURCE(IDB_TEXTURE),
|
|
TEXT("JPG"), &m_pDeviceObjects->m_pTexture );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Set per-frame states
|
|
SetPerFrameStates();
|
|
|
|
m_dwLastTick = GetTickCount();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//**********************************************************************************
|
|
VOID CTextScreensaver::SetPerFrameStates()
|
|
{
|
|
m_pd3dDevice->SetTexture( 0 , m_pDeviceObjects->m_pTexture );
|
|
|
|
// Set up texture pipeline
|
|
if ( m_SurfType == color )
|
|
{
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLOROP , D3DTOP_SELECTARG1 );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG1 , D3DTA_DIFFUSE );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE );
|
|
}
|
|
else
|
|
{
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLOROP , D3DTOP_MODULATE );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG1 , D3DTA_TEXTURE );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE );
|
|
}
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ALPHAOP , D3DTOP_DISABLE );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_MAGFILTER , D3DTEXF_LINEAR );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_MINFILTER , D3DTEXF_LINEAR );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_MIPFILTER , D3DTEXF_LINEAR );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ADDRESSU , D3DTADDRESS_WRAP );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_ADDRESSV , D3DTADDRESS_WRAP );
|
|
m_pd3dDevice->SetTextureStageState( 1 , D3DTSS_COLOROP , D3DTOP_DISABLE );
|
|
m_pd3dDevice->SetTextureStageState( 1 , D3DTSS_ALPHAOP , D3DTOP_DISABLE );
|
|
|
|
// Set up lighting
|
|
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING , TRUE );
|
|
if ( !m_bSpecular )
|
|
m_pd3dDevice->SetRenderState( D3DRS_AMBIENT , 0x646464 );
|
|
else
|
|
m_pd3dDevice->SetRenderState( D3DRS_AMBIENT , 0x464646 );
|
|
D3DLIGHT8 light;
|
|
light.Type = D3DLIGHT_DIRECTIONAL;
|
|
light.Diffuse = D3DXCOLOR(1,1,1,0);
|
|
light.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
|
|
light.Ambient = D3DXCOLOR(0,0,0,0);
|
|
light.Direction = D3DXVECTOR3(0.5,-0.5,1);
|
|
light.Position = D3DXVECTOR3(0,0,0);
|
|
light.Range = 10000;
|
|
light.Falloff = light.Attenuation0 = light.Attenuation1 = light.Attenuation2 = 0;
|
|
light.Phi = light.Theta = 0;
|
|
m_pd3dDevice->SetLight( 0 , &light );
|
|
m_pd3dDevice->LightEnable( 0 , TRUE );
|
|
|
|
// Set up material
|
|
D3DMATERIAL8 mat;
|
|
if ( m_SurfType == color )
|
|
{
|
|
DWORD dwColor;
|
|
if( m_bUseCustomColor )
|
|
dwColor = m_SurfaceColor;
|
|
else
|
|
dwColor = 0x00777777;
|
|
|
|
mat.Diffuse.r = FLOAT(dwColor&0xff)/255.0f;
|
|
mat.Diffuse.g = FLOAT((dwColor>>8)&0xff)/255.0f;
|
|
mat.Diffuse.b = FLOAT((dwColor>>16)&0xff)/255.0f;
|
|
}
|
|
else
|
|
{
|
|
mat.Diffuse = D3DXCOLOR(1,1,1,0);
|
|
}
|
|
mat.Ambient = mat.Diffuse;
|
|
mat.Specular = D3DXCOLOR(1.0f,1.0f,1.0f,0);
|
|
mat.Emissive = D3DXCOLOR(0,0,0,0);
|
|
mat.Power = 5;
|
|
m_pd3dDevice->SetMaterial( &mat );
|
|
|
|
// Set up texture coordinate generation if we're environment mapping or just force to passthrough
|
|
if ( m_SurfType == environment )
|
|
{
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXCOORDINDEX , D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXTURETRANSFORMFLAGS , D3DTTFF_COUNT2 );
|
|
|
|
D3DXMATRIX envmat;
|
|
D3DXMatrixIdentity( &envmat );
|
|
|
|
envmat._11 = envmat._22 = 0.5f;
|
|
envmat._31 = envmat._32 = 0.5f;
|
|
m_pd3dDevice->SetTransform( D3DTS_TEXTURE0 , &envmat );
|
|
}
|
|
else
|
|
{
|
|
D3DXMATRIX matWorldView;
|
|
D3DXMATRIX matWorldViewInv;
|
|
|
|
matWorldView = m_matWorld * m_matView;
|
|
D3DXMatrixInverse( &matWorldViewInv, NULL, &matWorldView );
|
|
m_pd3dDevice->SetTransform( D3DTS_TEXTURE0, &matWorldViewInv );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXCOORDINDEX , D3DTSS_TCI_CAMERASPACEPOSITION );
|
|
m_pd3dDevice->SetTextureStageState( 0 , D3DTSS_TEXTURETRANSFORMFLAGS , D3DTTFF_COUNT2 );
|
|
}
|
|
|
|
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE , FALSE );
|
|
m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE , FALSE );
|
|
m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE , m_bSpecular );
|
|
m_pd3dDevice->SetRenderState( D3DRS_WRAP0 , D3DWRAP_U|D3DWRAP_V );
|
|
m_pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE , FALSE );
|
|
|
|
m_pd3dDevice->SetTexture( 0, m_pDeviceObjects->m_pTexture );
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: InvalidateDeviceObjects()
|
|
// Desc:
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CTextScreensaver::InvalidateDeviceObjects()
|
|
{
|
|
SAFE_RELEASE(m_pDeviceObjects->m_pTexture);
|
|
SAFE_RELEASE(m_pDeviceObjects->m_pObject);
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: ConfirmDevice()
|
|
// Desc:
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT CTextScreensaver::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior,
|
|
D3DFORMAT fmtBackBuffer)
|
|
{
|
|
// Need D3DVTXPCAPS_TEXGEN for D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR
|
|
if( ( ( dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING ) ||
|
|
( dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING ) ) &&
|
|
( pCaps->VertexProcessingCaps & D3DVTXPCAPS_TEXGEN ) == 0 )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: SetDevice()
|
|
// Desc:
|
|
//-----------------------------------------------------------------------------
|
|
VOID CTextScreensaver::SetDevice( UINT iDevice )
|
|
{
|
|
m_pDeviceObjects = &m_DeviceObjects[iDevice];
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************************************
|
|
IDirect3DTexture8* CTextScreensaver::CreateTextureFromFile( const TCHAR* filename )
|
|
{
|
|
IDirect3DTexture8* texture;
|
|
if ( FAILED(D3DXCreateTextureFromFile( m_pd3dDevice , filename , &texture )) )
|
|
return NULL;
|
|
else
|
|
return texture;
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************************************
|
|
HRESULT CTextScreensaver::BuildTextMesh( const TCHAR* text )
|
|
{
|
|
// Release any old text mesh we built
|
|
SAFE_RELEASE(m_pDeviceObjects->m_pObject);
|
|
|
|
// Create temporary DC and select the correct font into it
|
|
HDC hdc = CreateDC( TEXT("DISPLAY") , NULL , NULL , NULL );
|
|
SelectObject( hdc , m_hFont );
|
|
|
|
TCHAR szText[MAX_DISPLAY_STRING+1];
|
|
lstrcpy( szText, text );
|
|
|
|
// Build new mesh
|
|
FLOAT max_deviation = 5.0f / FLOAT(m_dwMeshQuality+10);
|
|
GLYPHMETRICSFLOAT metrics[MAX_DISPLAY_STRING+1];
|
|
HRESULT rc;
|
|
rc = D3DXCreateText( m_pd3dDevice , hdc , szText , max_deviation, 0.5f , &m_pDeviceObjects->m_pObject , NULL, metrics );
|
|
if( FAILED( rc ) )
|
|
{
|
|
// We might have failed because the string had no glyphs, so try
|
|
// the default text instead
|
|
LoadString( NULL, IDS_DEFAULTTEXT, szText, MAX_DISPLAY_STRING );
|
|
rc = D3DXCreateText( m_pd3dDevice , hdc , szText , max_deviation, 0.5f , &m_pDeviceObjects->m_pObject , NULL, metrics );
|
|
}
|
|
|
|
// Delete temporary DC
|
|
DeleteDC( hdc );
|
|
if ( FAILED(rc) )
|
|
return rc;
|
|
|
|
// Compute the bounding box for the mesh by stepping through the glyph metrics structures
|
|
int len = lstrlen( szText );
|
|
m_fTextMinX = 1000000;
|
|
m_fTextMaxX = -1000000;
|
|
m_fTextMinY = 1000000;
|
|
m_fTextMaxY = -1000000;
|
|
FLOAT originx = 0;
|
|
FLOAT originy = 0;
|
|
GLYPHMETRICSFLOAT* pglyph = metrics;
|
|
for ( int i = 0 ; i < len ; i++ , pglyph++ )
|
|
{
|
|
if ( (pglyph->gmfptGlyphOrigin.x + originx) < m_fTextMinX )
|
|
m_fTextMinX = (pglyph->gmfptGlyphOrigin.x + originx);
|
|
if ( (pglyph->gmfptGlyphOrigin.x + originx + pglyph->gmfBlackBoxX) > m_fTextMaxX )
|
|
m_fTextMaxX = (pglyph->gmfptGlyphOrigin.x + originx + pglyph->gmfBlackBoxX);
|
|
|
|
if ( (pglyph->gmfptGlyphOrigin.y + originy) > m_fTextMaxY )
|
|
m_fTextMaxY = (pglyph->gmfptGlyphOrigin.y + originy);
|
|
if ( (pglyph->gmfptGlyphOrigin.y + originy - pglyph->gmfBlackBoxY) < m_fTextMinY )
|
|
m_fTextMinY = (pglyph->gmfptGlyphOrigin.y + originy - pglyph->gmfBlackBoxY);
|
|
|
|
originx += pglyph->gmfCellIncX;
|
|
originy += pglyph->gmfCellIncY;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//*********************************************************************************
|
|
VOID CTextScreensaver::UpdateAngles( DWORD elapsed )
|
|
{
|
|
static FLOAT x,y,z,t;
|
|
const FLOAT pi2 = 3.1415926536f * 2.0f;
|
|
|
|
FLOAT inc = FLOAT(elapsed * m_dwRotationSpeed);
|
|
|
|
switch ( m_RotType )
|
|
{
|
|
case spin:
|
|
y += inc * 0.00002f;
|
|
break;
|
|
|
|
case seesaw:
|
|
t += inc * 0.000025f;
|
|
y = (FLOAT(sin((t * pi2))) * 0.17f) + 1.0f;
|
|
break;
|
|
|
|
case wobble:
|
|
t += inc * 0.000025f;
|
|
y = (FLOAT(sin((t * pi2))) * 0.17f) + 1.0f;
|
|
z = (FLOAT(cos((t * pi2))) * 0.09f) + 1.0f;
|
|
break;
|
|
|
|
case tumble:
|
|
x += inc * 0.000004f;
|
|
y += inc * 0.000018f;
|
|
z += inc * 0.000007f;
|
|
break;
|
|
}
|
|
|
|
x = x - int(x);
|
|
y = y - int(y);
|
|
z = z - int(z);
|
|
|
|
m_fAngleX = x * pi2;
|
|
m_fAngleY = y * pi2;
|
|
m_fAngleZ = z * pi2;
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************************************
|
|
BOOL CTextScreensaver::UpdateTimeString( TCHAR* string )
|
|
{
|
|
TCHAR str[30];
|
|
|
|
GetTimeFormat( LOCALE_USER_DEFAULT, 0, NULL, NULL, str, 30 );
|
|
|
|
if ( lstrcmp( string , str ) )
|
|
{
|
|
lstrcpy( string , str );
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: ReadSettings()
|
|
// Desc:
|
|
//-----------------------------------------------------------------------------
|
|
VOID CTextScreensaver::ReadSettings()
|
|
{
|
|
HKEY hkey;
|
|
DWORD dwType = REG_DWORD;
|
|
DWORD dwLength = sizeof(DWORD);
|
|
|
|
// Defaults
|
|
LoadString( NULL, IDS_DEFAULTTEXT, m_szDisplayString, MAX_DISPLAY_STRING );
|
|
m_Font.lfHeight = 96;
|
|
m_Font.lfWidth = 0;
|
|
m_Font.lfEscapement = 0;
|
|
m_Font.lfOrientation = 0;
|
|
m_Font.lfWeight = 0;
|
|
m_Font.lfItalic = 0;
|
|
m_Font.lfUnderline = 0;
|
|
m_Font.lfStrikeOut = 0;
|
|
m_Font.lfCharSet = DEFAULT_CHARSET;
|
|
m_Font.lfOutPrecision = OUT_DEFAULT_PRECIS;
|
|
m_Font.lfClipPrecision = OUT_DEFAULT_PRECIS;
|
|
m_Font.lfQuality = DEFAULT_QUALITY;
|
|
m_Font.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
|
|
LoadString( NULL, IDS_FONT, m_Font.lfFaceName, LF_FACESIZE );
|
|
m_bDisplayTime = FALSE;
|
|
m_dwMeshQuality = 500;
|
|
m_SurfType = SurfType(environment);
|
|
m_bSpecular = TRUE;
|
|
m_dwRotationSpeed = 10;
|
|
m_dwSize = 10;
|
|
m_RotType = RotType(spin);
|
|
m_SurfaceColor = 0x00777777;
|
|
m_bUseCustomColor = FALSE;
|
|
m_bUseCustomTexture = FALSE;
|
|
m_bUseCustomEnvironment = FALSE;
|
|
lstrcpy( m_szCustomTexture, TEXT("") );
|
|
lstrcpy( m_szCustomEnvironment, TEXT("") );
|
|
|
|
// Read OpenGL settings first, so OS upgrade cases work
|
|
ss_ReadSettings();
|
|
|
|
if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, m_strRegPath,
|
|
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
|
|
{
|
|
dwLength = (MAX_DISPLAY_STRING + 1) * sizeof(TCHAR);
|
|
RegQueryValueEx( hkey, TEXT("DisplayString"), NULL, &dwType, (BYTE*)m_szDisplayString, &dwLength );
|
|
|
|
dwLength = sizeof(DWORD);
|
|
RegQueryValueEx( hkey, TEXT("FontHeight"), NULL, &dwType, (BYTE*)&m_Font.lfHeight, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("FontWeight"), NULL, &dwType, (BYTE*)&m_Font.lfWeight, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("FontItalic"), NULL, &dwType, (BYTE*)&m_Font.lfItalic, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("FontCharSet"), NULL, &dwType, (BYTE*)&m_Font.lfCharSet, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("FontPitchFamily"), NULL, &dwType, (BYTE*)&m_Font.lfPitchAndFamily, &dwLength );
|
|
|
|
dwLength = sizeof(m_Font.lfFaceName);
|
|
RegQueryValueEx( hkey, TEXT("FontFace"), NULL, &dwType, (BYTE*)m_Font.lfFaceName, &dwLength );
|
|
|
|
dwLength = sizeof(DWORD);
|
|
RegQueryValueEx( hkey, TEXT("DisplayTime"), NULL, &dwType, (BYTE*)&m_bDisplayTime, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("MeshQuality"), NULL, &dwType, (BYTE*)&m_dwMeshQuality, &dwLength );
|
|
if ( m_dwMeshQuality > 1000 )
|
|
m_dwMeshQuality = 1000;
|
|
|
|
RegQueryValueEx( hkey, TEXT("SurfaceType"), NULL, &dwType, (BYTE*)&m_SurfType, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("Specular"), NULL, &dwType, (BYTE*)&m_bSpecular, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("RotationSpeed"), NULL, &dwType, (BYTE*)&m_dwRotationSpeed, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("Size"), NULL, &dwType, (BYTE*)&m_dwSize, &dwLength );
|
|
if( m_dwSize < 1 )
|
|
m_dwSize = 1;
|
|
if( m_dwSize > 10 )
|
|
m_dwSize = 10;
|
|
|
|
RegQueryValueEx( hkey, TEXT("RotationStyle"), NULL, &dwType, (BYTE*)&m_RotType, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("SurfaceColor"), NULL, &dwType, (BYTE*)&m_SurfaceColor, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("UseCustomColor"), NULL, &dwType, (BYTE*)&m_bUseCustomColor, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("UseCustomTexture"), NULL, &dwType, (BYTE*)&m_bUseCustomTexture, &dwLength );
|
|
|
|
RegQueryValueEx( hkey, TEXT("UseCustomEnvironment"), NULL, &dwType, (BYTE*)&m_bUseCustomEnvironment, &dwLength );
|
|
|
|
dwLength = sizeof(m_szCustomTexture);
|
|
RegQueryValueEx( hkey, TEXT("CustomTexture"), NULL, &dwType, (BYTE*)m_szCustomTexture, &dwLength );
|
|
|
|
dwLength = sizeof(m_szCustomEnvironment);
|
|
RegQueryValueEx( hkey, TEXT("CustomEnvironment"), NULL, &dwType, (BYTE*)m_szCustomEnvironment, &dwLength );
|
|
|
|
ReadScreenSettings( hkey );
|
|
|
|
RegCloseKey( hkey );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: ss_ReadSettings()
|
|
// Desc:
|
|
//-----------------------------------------------------------------------------
|
|
VOID CTextScreensaver::ss_ReadSettings()
|
|
{
|
|
int options;
|
|
int optMask = 1;
|
|
|
|
// Get registry settings
|
|
if( ss_RegistrySetup( IDS_SAVERNAME, IDS_INIFILE ) )
|
|
{
|
|
// get demo type
|
|
int demoType = ss_GetRegistryInt( IDS_DEMOTYPE, 0 );
|
|
if( demoType == 1 )
|
|
{
|
|
m_bDisplayTime = TRUE;
|
|
}
|
|
|
|
// get rotation style
|
|
m_RotType = (RotType) (ss_GetRegistryInt( IDS_ROTSTYLE, 0 ) + 1); // add 1
|
|
if( m_RotType == 1 ) // 1==none,2=right,3=right,4=random->spin
|
|
m_RotType = none;
|
|
if( m_RotType > 3 )
|
|
m_RotType = spin;
|
|
|
|
// get tesselation
|
|
m_dwMeshQuality = ss_GetRegistryInt( IDS_TESSELATION, 0 ); // 0-100
|
|
m_dwMeshQuality = m_dwMeshQuality*10 + 1; // 1-1000
|
|
if ( m_dwMeshQuality > 1000 )
|
|
m_dwMeshQuality = 1000;
|
|
|
|
// get size
|
|
m_dwSize = ss_GetRegistryInt( IDS_SIZE, 0 ); // 0-100
|
|
m_dwSize = (unsigned) ( ((m_dwSize / 100.0f) * 90.0f + 10.0f) / 10.0f ); // 1-10
|
|
|
|
// get speed
|
|
m_dwRotationSpeed = ss_GetRegistryInt( IDS_SPEED, 0 ); // 0-100
|
|
m_dwRotationSpeed = (unsigned) ( ((m_dwRotationSpeed / 100.0f) * 190.0f + 10.0f) / 10.0f ); // 1-20
|
|
|
|
// get font, attributes, and charset
|
|
ss_GetRegistryString( IDS_FONT_REG, TEXT(""),
|
|
m_Font.lfFaceName, LF_FACESIZE );
|
|
|
|
options = ss_GetRegistryInt( IDS_FONT_ATTRIBUTES, 0 );
|
|
if( options >= 0 )
|
|
{
|
|
optMask = 1;
|
|
m_Font.lfWeight = ((options & optMask) != 0) ? FW_BOLD : FW_NORMAL;
|
|
optMask <<=1;
|
|
m_Font.lfItalic = ((options & optMask) != 0) ? (BYTE) 1 : 0;
|
|
}
|
|
|
|
m_Font.lfCharSet = (BYTE)ss_GetRegistryInt( IDS_CHARSET, 0 );
|
|
|
|
// get display string
|
|
ss_GetRegistryString( IDS_TEXT, TEXT(""), m_szDisplayString, MAX_DISPLAY_STRING );
|
|
|
|
m_SurfType = (SurfType) ss_GetRegistryInt( IDS_SURFSTYLE, color );
|
|
if( m_SurfType >= 1 )
|
|
m_SurfType = texture;
|
|
|
|
// Is there a texture specified in the registry that overrides the default?
|
|
ss_GetRegistryString( IDS_TEXTURE, NULL, m_szCustomTexture, MAX_PATH );
|
|
if( lstrlen( m_szCustomTexture ) > 0 )
|
|
{
|
|
m_bUseCustomTexture = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: ss_GetRegistryString()
|
|
// Desc:
|
|
//-----------------------------------------------------------------------------
|
|
BOOL CTextScreensaver::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_GetRegistryInt()
|
|
// Desc:
|
|
//-----------------------------------------------------------------------------
|
|
int CTextScreensaver::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 CTextScreensaver::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 CTextScreensaver::DoConfig()
|
|
{
|
|
ReadSettings();
|
|
DialogBox( NULL, MAKEINTRESOURCE( IDD_SETTINGS ),
|
|
m_hWndParent, (DLGPROC)SettingsDialogProcStub );
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL WINAPI CTextScreensaver::SettingsDialogProcStub( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
return g_pMyTextScreensaver->SettingsDialogProc( hDlg, message, wParam, lParam );
|
|
};
|
|
|
|
|
|
|
|
|
|
BOOL CTextScreensaver::SettingsDialogProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
switch ( message )
|
|
{
|
|
case WM_INITDIALOG:
|
|
InitItems( hDlg );
|
|
return FALSE;
|
|
|
|
case WM_COMMAND:
|
|
switch ( HIWORD(wParam) )
|
|
{
|
|
case BN_CLICKED:
|
|
{
|
|
switch( LOWORD(wParam) )
|
|
{
|
|
case IDOK:
|
|
ExtractAndWriteSettings( hDlg );
|
|
EndDialog( hDlg, TRUE );
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
ReadSettings();
|
|
EndDialog( hDlg, FALSE );
|
|
break;
|
|
|
|
case IDC_SELECT_FONT:
|
|
SelectFont( hDlg );
|
|
break;
|
|
|
|
case IDC_RADIO_TIME:
|
|
EnableWindow( GetDlgItem( hDlg , IDC_DISPLAY_STRING ) , FALSE );
|
|
break;
|
|
|
|
case IDC_RADIO_TEXT:
|
|
EnableWindow( GetDlgItem( hDlg , IDC_DISPLAY_STRING ) , TRUE );
|
|
break;
|
|
|
|
case IDC_RADIO_COLOR:
|
|
case IDC_RADIO_TEXTURE:
|
|
case IDC_RADIO_REFLECTION:
|
|
case IDC_USE_CUSTOM_COLOR:
|
|
case IDC_USE_CUSTOM_TEXTURE:
|
|
case IDC_USE_CUSTOM_ENVIRONMENT:
|
|
{
|
|
if( IsDlgButtonChecked( hDlg, IDC_RADIO_COLOR ) )
|
|
m_SurfType = color;
|
|
else if( IsDlgButtonChecked( hDlg, IDC_RADIO_TEXTURE ) )
|
|
m_SurfType = texture;
|
|
else if( IsDlgButtonChecked( hDlg, IDC_RADIO_REFLECTION ) )
|
|
m_SurfType = environment;
|
|
EnableTextureWindows( hDlg , SurfType(m_SurfType) );
|
|
}
|
|
break;
|
|
|
|
case IDC_SURFACE_COLOR:
|
|
SelectSurfaceColor( hDlg );
|
|
break;
|
|
|
|
case IDC_BROWSE_TEXTURE:
|
|
SelectCustomTexture( hDlg );
|
|
break;
|
|
|
|
case IDC_BROWSE_ENVIRONMENT:
|
|
SelectCustomEnvironment( hDlg );
|
|
break;
|
|
|
|
case IDC_SCREENSETTINGS:
|
|
DoScreenSettingsDialog( hDlg );
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case EN_CHANGE:
|
|
if ( LOWORD(wParam) == IDC_DISPLAY_STRING )
|
|
{
|
|
GetDlgItemText( hDlg , IDC_DISPLAY_STRING , m_szDisplayString , MAX_DISPLAY_STRING );
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID CTextScreensaver::InitItems( HWND hDlg )
|
|
{
|
|
TCHAR sz[100];
|
|
|
|
// Set the limit of the text box
|
|
SendDlgItemMessage( hDlg, IDC_DISPLAY_STRING, EM_SETLIMITTEXT, MAX_DISPLAY_STRING, 0 );
|
|
|
|
// Set the text string
|
|
SetDlgItemText( hDlg, IDC_DISPLAY_STRING, m_szDisplayString );
|
|
|
|
// Set the radio button for time/text display
|
|
if ( m_bDisplayTime )
|
|
{
|
|
EnableWindow( GetDlgItem( hDlg, IDC_DISPLAY_STRING ), FALSE );
|
|
CheckRadioButton( hDlg, IDC_RADIO_TIME, IDC_RADIO_TEXT, IDC_RADIO_TIME );
|
|
}
|
|
else
|
|
{
|
|
EnableWindow( GetDlgItem( hDlg, IDC_DISPLAY_STRING ), TRUE );
|
|
CheckRadioButton( hDlg, IDC_RADIO_TIME, IDC_RADIO_TEXT, IDC_RADIO_TEXT );
|
|
}
|
|
|
|
switch( m_SurfType )
|
|
{
|
|
case color:
|
|
CheckRadioButton( hDlg, IDC_RADIO_COLOR, IDC_RADIO_REFLECTION, IDC_RADIO_COLOR );
|
|
break;
|
|
case texture:
|
|
CheckRadioButton( hDlg, IDC_RADIO_COLOR, IDC_RADIO_REFLECTION, IDC_RADIO_TEXTURE );
|
|
break;
|
|
case environment:
|
|
CheckRadioButton( hDlg, IDC_RADIO_COLOR, IDC_RADIO_REFLECTION, IDC_RADIO_REFLECTION );
|
|
break;
|
|
}
|
|
|
|
// Check/uncheck the specular box
|
|
SendDlgItemMessage( hDlg, IDC_SPECULAR, BM_SETCHECK,
|
|
m_bSpecular ? BST_CHECKED : BST_UNCHECKED, 0 );
|
|
|
|
// Enable/disable surface color button
|
|
EnableWindow( GetDlgItem( hDlg, IDC_SURFACE_COLOR ), m_SurfType == color );
|
|
|
|
// Check/uncheck the custom texture boxes
|
|
SendDlgItemMessage( hDlg, IDC_USE_CUSTOM_COLOR, BM_SETCHECK,
|
|
m_bUseCustomColor ? BST_CHECKED : BST_UNCHECKED, 0 );
|
|
SendDlgItemMessage( hDlg, IDC_USE_CUSTOM_TEXTURE, BM_SETCHECK,
|
|
m_bUseCustomTexture ? BST_CHECKED : BST_UNCHECKED, 0 );
|
|
SendDlgItemMessage( hDlg, IDC_USE_CUSTOM_ENVIRONMENT, BM_SETCHECK,
|
|
m_bUseCustomEnvironment ? BST_CHECKED : BST_UNCHECKED, 0 );
|
|
|
|
// Enable all the texture windows as appropriate
|
|
EnableTextureWindows( hDlg, m_SurfType );
|
|
|
|
// Fill the rotation style combo box
|
|
LoadString( NULL, IDS_NONE, sz, 100 );
|
|
SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
|
|
LoadString( NULL, IDS_SPIN, sz, 100 );
|
|
SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
|
|
LoadString( NULL, IDS_SEESAW, sz, 100 );
|
|
SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
|
|
LoadString( NULL, IDS_WOBBLE, sz, 100 );
|
|
SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
|
|
LoadString( NULL, IDS_TUMBLE, sz, 100 );
|
|
SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_ADDSTRING, 0, (LPARAM) sz );
|
|
|
|
// Set the current rotation style selection
|
|
SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_SETCURSEL, m_RotType, 0 );
|
|
|
|
// Set up the rotation speed slider
|
|
SendDlgItemMessage( hDlg, IDC_ROTATION_SPEED, TBM_SETRANGE, TRUE, MAKELONG(1,20) );
|
|
SendDlgItemMessage( hDlg, IDC_ROTATION_SPEED, TBM_SETPOS, TRUE, m_dwRotationSpeed );
|
|
|
|
// Set up the resolution slider
|
|
SendDlgItemMessage( hDlg, IDC_RESOLUTION, TBM_SETRANGE, TRUE, MAKELONG(1,10) );
|
|
SendDlgItemMessage( hDlg, IDC_RESOLUTION, TBM_SETPOS, TRUE, m_dwMeshQuality / 100 );
|
|
|
|
// Set up the size slider
|
|
SendDlgItemMessage( hDlg, IDC_VIEWPORTSIZE, TBM_SETRANGE, TRUE, MAKELONG(1,10) );
|
|
SendDlgItemMessage( hDlg, IDC_VIEWPORTSIZE, TBM_SETPOS, TRUE, m_dwSize );
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID CTextScreensaver::ExtractAndWriteSettings( HWND hDlg )
|
|
{
|
|
LRESULT ret;
|
|
HKEY hkey = NULL;
|
|
|
|
m_bSpecular = IsDlgButtonChecked( hDlg, IDC_SPECULAR );
|
|
|
|
m_bUseCustomColor = IsDlgButtonChecked( hDlg, IDC_USE_CUSTOM_COLOR );
|
|
m_bUseCustomTexture = IsDlgButtonChecked( hDlg, IDC_USE_CUSTOM_TEXTURE );
|
|
m_bUseCustomEnvironment = IsDlgButtonChecked( hDlg, IDC_USE_CUSTOM_ENVIRONMENT );
|
|
|
|
if ( (ret = SendDlgItemMessage( hDlg, IDC_ROTATION_STYLE, CB_GETCURSEL, 0, 0 )) != CB_ERR )
|
|
m_RotType = RotType(ret);
|
|
|
|
m_dwSize = (DWORD)SendDlgItemMessage( hDlg, IDC_VIEWPORTSIZE, TBM_GETPOS, 0, 0 );
|
|
m_dwRotationSpeed = (DWORD)SendDlgItemMessage( hDlg, IDC_ROTATION_SPEED, TBM_GETPOS, 0, 0 );
|
|
m_dwMeshQuality = 100 * (DWORD)SendDlgItemMessage( hDlg, IDC_RESOLUTION, TBM_GETPOS, 0, 0 );
|
|
|
|
GetDlgItemText( hDlg, IDC_DISPLAY_STRING, m_szDisplayString, MAX_DISPLAY_STRING + 1 );
|
|
|
|
if ( IsDlgButtonChecked( hDlg, IDC_RADIO_TIME ) )
|
|
m_bDisplayTime = TRUE;
|
|
else
|
|
m_bDisplayTime = FALSE;
|
|
|
|
if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, m_strRegPath,
|
|
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
|
|
{
|
|
WriteScreenSettings( hkey );
|
|
RegSetValueEx( hkey, TEXT("SurfaceType"), NULL, REG_DWORD, (BYTE*)&m_SurfType, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("Specular"), NULL, REG_DWORD, (BYTE*)&m_bSpecular, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("SurfaceColor"), NULL, REG_DWORD, (BYTE*)&m_SurfaceColor, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("CustomTexture"), NULL, REG_SZ, (BYTE*)&m_szCustomTexture, (lstrlen(m_szCustomTexture) + 1) * sizeof(TCHAR) );
|
|
RegSetValueEx( hkey, TEXT("CustomEnvironment"), NULL, REG_SZ, (BYTE*)&m_szCustomEnvironment, (lstrlen(m_szCustomEnvironment) + 1) * sizeof(TCHAR) );
|
|
RegSetValueEx( hkey, TEXT("UseCustomColor"), NULL, REG_DWORD, (BYTE*)&m_bUseCustomColor, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("UseCustomTexture"), NULL, REG_DWORD, (BYTE*)&m_bUseCustomTexture, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("UseCustomEnvironment"), NULL, REG_DWORD, (BYTE*)&m_bUseCustomEnvironment, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("MeshQuality"), NULL, REG_DWORD, (BYTE*)&m_dwMeshQuality, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("Size"), NULL, REG_DWORD, (BYTE*)&m_dwSize, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("RotationSpeed"), NULL, REG_DWORD, (BYTE*)&m_dwRotationSpeed, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("RotationStyle"), NULL, REG_DWORD, (BYTE*)&m_RotType, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("DisplayString"), NULL, REG_SZ, (BYTE*)&m_szDisplayString, (lstrlen(m_szDisplayString) + 1) * sizeof(TCHAR) );
|
|
RegSetValueEx( hkey, TEXT("DisplayTime"), NULL, REG_DWORD, (BYTE*)&m_bDisplayTime, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("FontWeight"), NULL, REG_DWORD, (BYTE*)&m_Font.lfWeight, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("FontHeight"), NULL, REG_DWORD, (BYTE*)&m_Font.lfHeight, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("FontItalic"), NULL, REG_DWORD, (BYTE*)&m_Font.lfItalic, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("FontCharSet"), NULL, REG_DWORD, (BYTE*)&m_Font.lfCharSet, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("FontPitchFamily"), NULL, REG_DWORD, (BYTE*)&m_Font.lfPitchAndFamily, sizeof(DWORD) );
|
|
RegSetValueEx( hkey, TEXT("FontFace"), NULL, REG_SZ, (BYTE*)&m_Font.lfFaceName, (lstrlen(m_Font.lfFaceName) + 1) * sizeof(TCHAR) );
|
|
RegCloseKey( hkey );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************************************
|
|
VOID CTextScreensaver::SelectSurfaceColor( HWND hDlg )
|
|
{
|
|
static COLORREF cust_colors[16];
|
|
|
|
CHOOSECOLOR choose;
|
|
choose.lStructSize = sizeof(choose);
|
|
choose.hwndOwner = hDlg;
|
|
choose.hInstance = HWND(m_hInstance);
|
|
choose.rgbResult = m_SurfaceColor;
|
|
choose.lpCustColors = cust_colors;
|
|
choose.Flags = CC_ANYCOLOR|CC_FULLOPEN|CC_RGBINIT;
|
|
choose.lCustData = 0;
|
|
choose.lpfnHook = NULL;
|
|
choose.lpTemplateName = NULL;
|
|
|
|
if ( ChooseColor( &choose ) )
|
|
m_SurfaceColor = choose.rgbResult;
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************************************
|
|
VOID CTextScreensaver::SelectFont( HWND hDlg )
|
|
{
|
|
CHOOSEFONT choose;
|
|
|
|
choose.lStructSize = sizeof(choose);
|
|
choose.hwndOwner = hDlg;
|
|
choose.hDC;
|
|
choose.iPointSize = 720;
|
|
choose.lpLogFont = &m_Font;
|
|
choose.Flags = CF_TTONLY|CF_FORCEFONTEXIST|CF_NOVERTFONTS|CF_SCREENFONTS|CF_INITTOLOGFONTSTRUCT|CF_ENABLETEMPLATE;
|
|
choose.lpTemplateName = MAKEINTRESOURCE(DLG_SELECT_FONT);
|
|
choose.hInstance = m_hInstance;
|
|
|
|
if ( ChooseFont( &choose ) )
|
|
m_Font = *choose.lpLogFont;
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************************************
|
|
VOID CTextScreensaver::SelectCustomTexture( HWND hDlg )
|
|
{
|
|
TCHAR fn[MAX_PATH] = TEXT("\0");
|
|
TCHAR strTitle[100];
|
|
LoadString( NULL, IDS_OPENTEXTURETITLE, strTitle, 100 );
|
|
|
|
lstrcpy( fn, m_szCustomTexture );
|
|
|
|
TCHAR filter[200];
|
|
LoadString( NULL, IDS_FILEFILTER, filter, 200);
|
|
for( TCHAR* pch = filter; *pch != TEXT('\0'); pch++ )
|
|
{
|
|
if( *pch == TEXT('#') )
|
|
*pch = TEXT('\0');
|
|
}
|
|
|
|
TCHAR szWindowsDir[MAX_PATH];
|
|
szWindowsDir[0] = TEXT('\0');
|
|
GetWindowsDirectory( szWindowsDir, MAX_PATH );
|
|
|
|
OPENFILENAME ofn;
|
|
memset( &ofn , 0 , sizeof(ofn) );
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = hDlg;
|
|
ofn.hInstance = m_hInstance;
|
|
ofn.lpstrFilter = filter;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = fn;
|
|
ofn.nMaxFile = sizeof(fn);
|
|
ofn.lpstrTitle = strTitle;
|
|
ofn.Flags = OFN_ENABLESIZING|OFN_FILEMUSTEXIST;
|
|
ofn.lpstrDefExt = TEXT("mid");
|
|
if( lstrlen( fn ) == 0 )
|
|
ofn.lpstrInitialDir = szWindowsDir;
|
|
|
|
if ( GetOpenFileName( &ofn ) )
|
|
lstrcpy( m_szCustomTexture , ofn.lpstrFile );
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************************************
|
|
VOID CTextScreensaver::SelectCustomEnvironment( HWND hDlg )
|
|
{
|
|
TCHAR fn[MAX_PATH] = TEXT("\0");
|
|
TCHAR strTitle[100];
|
|
LoadString( NULL, IDS_OPENENVIRONMENTMAPTITLE, strTitle, 100 );
|
|
|
|
TCHAR filter[200];
|
|
LoadString( NULL, IDS_FILEFILTER, filter, 200);
|
|
for( TCHAR* pch = filter; *pch != TEXT('\0'); pch++ )
|
|
{
|
|
if( *pch == TEXT('#') )
|
|
*pch = TEXT('\0');
|
|
}
|
|
|
|
TCHAR szWindowsDir[MAX_PATH];
|
|
szWindowsDir[0] = TEXT('\0');
|
|
GetWindowsDirectory( szWindowsDir, MAX_PATH );
|
|
|
|
OPENFILENAME ofn;
|
|
memset( &ofn , 0 , sizeof(ofn) );
|
|
ofn.lStructSize = sizeof(ofn);
|
|
ofn.hwndOwner = hDlg;
|
|
ofn.hInstance = m_hInstance;
|
|
ofn.lpstrFilter = filter;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = fn;
|
|
ofn.nMaxFile = sizeof(fn);
|
|
ofn.lpstrTitle = strTitle;
|
|
ofn.Flags = OFN_ENABLESIZING|OFN_FILEMUSTEXIST;
|
|
ofn.lpstrDefExt = TEXT("mid");
|
|
if( lstrlen( fn ) == 0 )
|
|
ofn.lpstrInitialDir = szWindowsDir;
|
|
|
|
if ( GetOpenFileName( &ofn ) )
|
|
lstrcpy( m_szCustomEnvironment , ofn.lpstrFile );
|
|
}
|
|
|
|
|
|
|
|
|
|
//***************************************************************************************
|
|
VOID CTextScreensaver::EnableTextureWindows( HWND hDlg , SurfType sel )
|
|
{
|
|
HWND use_color = GetDlgItem( hDlg , IDC_USE_CUSTOM_COLOR );
|
|
HWND use_texture = GetDlgItem( hDlg , IDC_USE_CUSTOM_TEXTURE );
|
|
HWND use_environ = GetDlgItem( hDlg , IDC_USE_CUSTOM_ENVIRONMENT );
|
|
HWND browse_color = GetDlgItem( hDlg , IDC_SURFACE_COLOR );
|
|
HWND browse_texture = GetDlgItem( hDlg , IDC_BROWSE_TEXTURE );
|
|
HWND browse_environ = GetDlgItem( hDlg , IDC_BROWSE_ENVIRONMENT );
|
|
|
|
BOOL color_checked = IsDlgButtonChecked( hDlg , IDC_USE_CUSTOM_COLOR );
|
|
BOOL texture_checked = IsDlgButtonChecked( hDlg , IDC_USE_CUSTOM_TEXTURE );
|
|
BOOL environment_checked = IsDlgButtonChecked( hDlg , IDC_USE_CUSTOM_ENVIRONMENT );
|
|
|
|
switch ( sel )
|
|
{
|
|
case environment:
|
|
EnableWindow( use_color , FALSE );
|
|
EnableWindow( use_texture , FALSE );
|
|
EnableWindow( use_environ , TRUE );
|
|
EnableWindow( browse_color , FALSE );
|
|
EnableWindow( browse_texture , FALSE );
|
|
EnableWindow( browse_environ , environment_checked );
|
|
break;
|
|
|
|
case texture:
|
|
EnableWindow( use_color , FALSE );
|
|
EnableWindow( use_texture , TRUE );
|
|
EnableWindow( use_environ , FALSE );
|
|
EnableWindow( browse_color , FALSE );
|
|
EnableWindow( browse_texture , texture_checked );
|
|
EnableWindow( browse_environ , FALSE );
|
|
break;
|
|
|
|
case color:
|
|
default:
|
|
EnableWindow( use_color , TRUE );
|
|
EnableWindow( use_texture , FALSE );
|
|
EnableWindow( use_environ , FALSE );
|
|
EnableWindow( browse_color , color_checked );
|
|
EnableWindow( browse_texture , FALSE );
|
|
EnableWindow( browse_environ , FALSE );
|
|
break;
|
|
}
|
|
}
|
|
|