blob: e2b2130d9dfa4cc1346c57a8d5846fe3975d35eb [file] [log] [blame]
/**
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2004 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
/**
* $Id: wprojectMsaver.cpp,v 1.4 2004/11/15 15:09:44 cvs Exp $
*
* projectM-based screensaver for Windows
*
*/
#include <windows.h>
#include <stdio.h>
#include <regstr.h>
#include <math.h>
#include "resource.h"
#include "tsaver.h"
#ifdef WIN32
extern "C" {
#include <projectM/projectM.hpp>
}
#endif /** WIN32 */
#ifdef DEBUG
FILE *debugFile = NULL;
#endif
//#pragma warning(disable: 4800)
//#pragma warning(disable: 4305)
//#pragma warning(disable: 4244)
HINSTANCE hInstance=NULL;
HWND hScrWindow=NULL;
TSaverSettings *ss=NULL;
/** Name */
TCHAR szAppName[32];
/** Visualiser */
projectM_t *globalPM = NULL;
void initGL(int width, int height)
{
projectM_resetGL( globalPM, width, height );
switchPreset( RANDOM_NEXT, HARD_CUT );
}
void display() {
int i;
short pcm_data[2][512];
/** Produce some fake PCM data to stuff into projectM */
if ( globalPM->count % 5 == 0 ) {
for ( i = 0 ; i < 512 ; i++ ) {
pcm_data[0][i] = 0;
pcm_data[1][i] = 0;
}
} else {
for ( i = 0 ; i < 512 ; i++ ) {
if ( i % 2 == 0 ) {
pcm_data[0][i] = (float)( rand() / ( (float)RAND_MAX ) * (pow(2,i%14) ) );
pcm_data[1][i] = (float)( rand() / ( (float)RAND_MAX ) * (pow(2,i/2%14) ) );
} else {
pcm_data[0][i] = (float)( rand() / ( (float)RAND_MAX ) * (pow(2,i/2%14) ) );
pcm_data[1][i] = (float)( rand() / ( (float)RAND_MAX ) * (pow(2,i%14) ) );
}
if ( i % 2 == 1 ) {
pcm_data[0][i] = -pcm_data[0][i];
pcm_data[1][i] = -pcm_data[1][i];
}
}
}
/** Add the waveform data */
addPCM16( pcm_data );
/** Render the new frame */
renderFrame( globalPM );
}
BOOL VerifyPassword(HWND hwnd)
{
// Under NT, we return true immediately. This lets the saver quit, and the system manages passwords.
// Under '95, we call VerifyScreenSavePwd. This checks the appropriate registry key and, if necessary, pops up a verify dialog
OSVERSIONINFO osv;
osv.dwOSVersionInfoSize = sizeof(osv);
GetVersionEx(&osv);
if( osv.dwPlatformId==VER_PLATFORM_WIN32_NT )
return true;
HINSTANCE hpwdcpl = ::LoadLibrary("PASSWORD.CPL");
if( hpwdcpl==NULL )
return true;
typedef BOOL (WINAPI *VERIFYSCREENSAVEPWD)(HWND hwnd);
VERIFYSCREENSAVEPWD VerifyScreenSavePwd;
VerifyScreenSavePwd = (VERIFYSCREENSAVEPWD)GetProcAddress(hpwdcpl,"VerifyScreenSavePwd");
if( VerifyScreenSavePwd==NULL )
{
FreeLibrary(hpwdcpl);
return true;
}
BOOL bres = VerifyScreenSavePwd(hwnd);
FreeLibrary(hpwdcpl);
return bres;
}
void ChangePassword(HWND hwnd)
{
// This only ever gets called under '95, when started with the /a option.
HINSTANCE hmpr = ::LoadLibrary("MPR.DLL");
if( hmpr==NULL )
return;
typedef VOID (WINAPI *PWDCHANGEPASSWORD) (LPCSTR lpcRegkeyname,HWND hwnd,UINT uiReserved1,UINT uiReserved2);
PWDCHANGEPASSWORD PwdChangePassword=(PWDCHANGEPASSWORD)::GetProcAddress(hmpr,"PwdChangePasswordA");
if( PwdChangePassword==NULL )
{
FreeLibrary(hmpr);
return;
}
PwdChangePassword("SCRSAVE",hwnd,0,0); FreeLibrary(hmpr);
}
LRESULT CALLBACK SaverWindowProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
// If you have a problem that's really not going away, put a debug in here:
// Debug(MessageName(msg));
// This will make a log of every single message that gets sent to the window.
static PAINTSTRUCT ps;
switch (msg)
{
case WM_CREATE:
{
ss->hwnd=hwnd;
GetCursorPos(&(ss->InitCursorPos));
ss->InitTime=GetTickCount();
} break;
case WM_ACTIVATE:
case WM_ACTIVATEAPP:
case WM_NCACTIVATE:
{
if( ScrMode==smSaver && !ss->IsDialogActive && LOWORD(wParam)==WA_INACTIVE )
ss->CloseSaverWindow();
} break;
case WM_SETCURSOR:
{
if( ScrMode==smSaver && !ss->IsDialogActive )
SetCursor(NULL);
else
SetCursor(LoadCursor(NULL,IDC_ARROW));
} break;
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_KEYDOWN:
{
#ifdef DEBUG
fprintf( debugFile, "key: %d\n", (int)wParam );
fflush( debugFile );
#endif
if ( ScrMode == smSaver && !ss->IsDialogActive ) {
if ( (int)wParam == 'R' ) {
switchPreset( RANDOM_NEXT, HARD_CUT );
} else {
if ( (int)wParam == 'N' ) {
switchPreset( ALPHA_NEXT, HARD_CUT );
} else {
if ( (int)wParam == 'P' ) {
switchPreset( ALPHA_PREVIOUS, HARD_CUT );
}
}
}
} else {
ss->CloseSaverWindow();
}
} break;
case WM_MOUSEMOVE:
{
if( ScrMode==smSaver && !ss->IsDialogActive )
{
POINT pt;
GetCursorPos(&pt);
int dx = pt.x-ss->InitCursorPos.x;
if( dx<0 )
dx = -dx;
int dy = pt.y-ss->InitCursorPos.y;
if( dy<0 )
dy = -dy;
if( dx>(int)ss->MouseThreshold || dy>(int)ss->MouseThreshold )
ss->CloseSaverWindow();
}
} break;
case (WM_SYSCOMMAND):
{
if( ScrMode==smSaver )
{
if( wParam==SC_SCREENSAVE )
return false;
if( wParam==SC_CLOSE )
return false;
}
} break;
case (WM_CLOSE):
{
if( ScrMode==smSaver && ss->ReallyClose && !ss->IsDialogActive )
{
BOOL CanClose = true;
if( GetTickCount()-ss->InitTime > 1000*ss->PasswordDelay )
{
ss->StartDialog();
CanClose = VerifyPassword(hwnd);
ss->EndDialog();
}
if( CanClose )
DestroyWindow(hwnd);
}
if( ScrMode==smSaver )
return false; // so that DefWindowProc doesn't get called, because it would just DestroyWindow
} break;
case (WM_DESTROY):
{
if( ss->idTimer!=0 )
KillTimer(hwnd,ss->idTimer);
ss->idTimer=0;
PostQuitMessage(0);
} break;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
void DoSaver(HWND hparwnd, int nCmdShow)
{
WNDCLASS wc;
wc.style=CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = SaverWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";
if( !RegisterClass(&wc) ) {
MessageBox(NULL, "RegisterClass() failed: "
"Cannot register window class.", "Error", MB_OK);
return;
}
int cx, cy;
if( ScrMode==smPreview )
{
RECT rc;
GetWindowRect(hparwnd,&rc);
cx = rc.right - rc.left;
cy = rc.bottom - rc.top;
hScrWindow =
CreateWindow("OpenGL", "SaverWindow", WS_CHILD|WS_VISIBLE,0, 0, cx, cy, hparwnd, NULL, hInstance, NULL);
}
else
{
cx = GetSystemMetrics(SM_CXSCREEN);
cy = GetSystemMetrics(SM_CYSCREEN);
DWORD exstyle, style;
exstyle = WS_EX_TOPMOST;
style = WS_POPUP|WS_VISIBLE;
hScrWindow = CreateWindow ("OpenGL", "SaverWindow", style,0, 0, cx, cy, NULL, NULL, hInstance, NULL);
}
if( hScrWindow==NULL )
return;
UINT oldval;
if( ScrMode==smSaver )
SystemParametersInfo(SPI_SCREENSAVERRUNNING,1,&oldval,0);
HDC hDC = ::GetDC(hScrWindow);
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
int pf = ChoosePixelFormat(hDC, &pfd);
if (pf == 0) {
MessageBox(NULL, "ChoosePixelFormat() failed: "
"Cannot find a suitable pixel format.", "Error", MB_OK);
return;
}
if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
MessageBox(NULL, "SetPixelFormat() failed: "
"Cannot set format specified.", "Error", MB_OK);
return;
}
DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
HGLRC hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
initGL(cx, cy);
ShowWindow(hScrWindow, nCmdShow);
MSG msg;
bool done = false;
while(!done) // Loop That Runs While done=FALSE
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting?
{
if (msg.message==WM_QUIT) // Have We Received A Quit Message?
done=TRUE; // If So done=TRUE
else // If Not, Deal With Window Messages
{
TranslateMessage(&msg); // Translate The Message
DispatchMessage(&msg); // Dispatch The Message
}
}
else // If There Are No Messages
{
// display(cx, cy );
display();
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
//Sleep(10);
}
}
wglMakeCurrent(NULL, NULL);
ReleaseDC(hScrWindow, hDC);
wglDeleteContext(hRC);
if( ScrMode==smSaver )
SystemParametersInfo(SPI_SCREENSAVERRUNNING,0,&oldval,0);
return;
}
BOOL CALLBACK ConfigDialogProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
CheckDlgButton(hwnd,IDC_FLASH,ss->Rotate);
return true;
}
case WM_COMMAND:
{
int id=LOWORD(wParam);
if( id==IDOK )
{
ss->Rotate = (IsDlgButtonChecked(hwnd,IDC_FLASH)==BST_CHECKED);
ss->WriteConfigRegistry();
}
if( id==IDOK || id==IDCANCEL )
EndDialog(hwnd,id);
} break;
}
return false;
}
int WINAPI WinMain(HINSTANCE h, HINSTANCE,LPSTR,int nCmdShow)
{
hInstance = h;
LoadString( hInstance, IDS_APPNAME, szAppName, 31 );
char *c = GetCommandLine();
if(*c == '\"' )
{
c++;
while( *c!=0 && *c!='\"' )
c++;
}
else
{
while( *c!=0 && *c!=' ' )
c++;
}
if( *c!=0 )
c++;
while( *c==' ' )
c++;
HWND hwnd=NULL;
if( *c==0 )
{
ScrMode = smConfig;
hwnd=NULL;
}
else
{
if( *c=='-' || *c=='/' )
c++;
if( *c=='p' || *c=='P' || *c=='l' || *c=='L' )
{
c++;
while( *c==' ' || *c==':' )
c++;
hwnd = (HWND)atoi(c);
ScrMode = smPreview;
}
else if( *c=='s' || *c=='S' )
{
ScrMode=smSaver;
}
else if( *c=='c' || *c=='C' )
{
c++;
while( *c==' ' || *c==':' )
c++;
if( *c==0 )
hwnd = GetForegroundWindow();
else
hwnd = (HWND)atoi(c);
ScrMode = smConfig;
}
else if( *c=='a' || *c=='A' )
{
c++;
while( *c==' ' || *c==':' )
c++;
hwnd = (HWND)atoi(c);
ScrMode = smPassword;
}
}
/** Set the app name */
// LoadString( hInstance, IDS_APPNAME, szAppName, 31 );
// We create a global TSaverSettings here, for convenience. It will get used by the config dialog and
// by the saver as it runs
ss = new TSaverSettings();
ss->ReadGeneralRegistry();
ss->ReadConfigRegistry();
if( ScrMode==smPassword )
ChangePassword(hwnd);
if( ScrMode==smConfig )
DialogBox(hInstance,MAKEINTRESOURCE(DLG_CONFIG),hwnd,ConfigDialogProc);
if( ScrMode == smSaver || ScrMode==smPreview ) {
#ifdef DEBUG
debugFile = fopen( "c:\\wprojectMsaver.txt", "w" );
#endif
/** Initialise projectM */
globalPM = (projectM_t *)wipemalloc( sizeof( projectM_t ) );
projectM_reset( globalPM );
#ifdef DEBUG
fprintf( debugFile, "here1\n" );
fflush( debugFile );
#endif
globalPM->fullscreen = 0;
globalPM->texsize = 512;
globalPM->fontURL = (char *)malloc( sizeof( char ) * 512 );
strcpy( globalPM->fontURL, "c:\\Program Files\\projectM\\fonts" );
globalPM->presetURL = (char *)malloc( sizeof( char ) * 512 );
strcpy( globalPM->presetURL, "c:\\Program Files\\projectM\\presets" );
projectM_init( globalPM );
#ifdef DEBUG
fprintf( debugFile, "here2\n" );
fflush( debugFile );
#endif
DoSaver(hwnd, nCmdShow);
}
delete ss;
return 0;
}