import matrix screensaver secon try

svn path=/trunk/; revision=21629
This commit is contained in:
Magnus Olsen 2006-04-17 10:56:11 +00:00
parent f31166fa5c
commit 659c768c6e
18 changed files with 2000 additions and 0 deletions

View file

@ -0,0 +1,17 @@
Matrrix2 screensaver for ReactOS
/*****************************************
Freeware
Copyright J Brown 2003
Updates at http://www.catch22.net
******************************************/
The author has given permission to use these sources
under Public Domain. Do what thou will but please give
credit where credit is due.
-Magnus Olsen (aka GreatLord) / Aleasky (aka Fireball)

View file

@ -0,0 +1,32 @@
Matrix ScreenSaver 2.0
www.catch22.ork.uk
Freeware written by J Brown 2003
------------------------------------
The Matrix ScreenSaver is a small, fast and elegant Windows
version of the green "Matrix" cypher-code seen in the films.
With this version you can even add messages which are
decoded displayed in realtime.
Features
------------------------------------
+ Small and FAST (50Kb!)
+ All 32bit versions of Windows (Win95,98,ME,NT,2000,XP,NET)
+ Multimonitor support (new in version 2)
+ Custom matrix messages
+ Highly configurable
+ Full sourcecode available!
Installation and use
------------------------------------
Simply copy "matrix.scr" to your windows directory,
or right-click this file in explorer and click "Install".
Other than that, it's just a standard Windows screensaver so it
works just like any other screensaver

View file

@ -0,0 +1,310 @@
//
// config.c
//
// Screensaver Configuration dialog
//
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
#include "globals.h"
#include "message.h"
#include "matrix.h"
// needed for slider-controls
#pragma comment(lib, "comctl32.lib")
//
// Called once for every font - add to list
//
int CALLBACK EnumFontProc(ENUMLOGFONT *lpelfe, NEWTEXTMETRIC *lpntme, int FontType, LPARAM lParam)
{
SendMessage((HWND)lParam, CB_ADDSTRING, 0, (LPARAM)lpelfe->elfLogFont.lfFaceName);
return 1;
}
//
// Add every fontname into specified combobox
//
void AddFonts(HWND hwndCombo)
{
HDC hdc;
LOGFONT lf;
lf.lfCharSet = ANSI_CHARSET;
lf.lfPitchAndFamily = 0;
lf.lfFaceName[0] = '\0';
hdc = GetDC(0);
EnumFontFamiliesEx(hdc, &lf, (FONTENUMPROC)EnumFontProc, (LONG)hwndCombo, 0);
ReleaseDC(0, hdc);
}
//
// Redraw preview control with current font/fontsize
//
void UpdatePreview(HWND hwnd)
{
g_nFontSize = SendDlgItemMessage(hwnd, IDC_SLIDER4, TBM_GETPOS,0, 0);
SetMessageFont(hwnd, g_szFontName, g_nFontSize, g_fFontBold);
InvalidateRect(GetDlgItem(hwnd, IDC_PREVIEW), 0, 0);
}
//
// Dialogbox procedure for Configuration window
//
BOOL CALLBACK ConfigDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static char buf[256];
HWND hwndCombo, hwndCtrl;
int index, items, val;
RECT rect;
static int prevwidth, prevheight;
switch(uMsg)
{
case WM_INITDIALOG:
prevwidth = GetSystemMetrics(SM_CXSCREEN) / GLYPH_WIDTH;
prevheight = GetSystemMetrics(SM_CYSCREEN) / GLYPH_HEIGHT + 1;
//Add any saved messages to the combo box
for(index = 0; index < g_nNumMessages; index++)
{
if(lstrlen(g_szMessages[index]) > 0)
SendDlgItemMessage(hwnd, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)g_szMessages[index]);
}
//select the first message, and preview it
SendDlgItemMessage(hwnd, IDC_COMBO1, CB_SETCURSEL, 0, 0);
SendDlgItemMessage(hwnd, IDC_SLIDER1, TBM_SETRANGE, 0, MAKELONG(SPEED_MIN, SPEED_MAX));
SendDlgItemMessage(hwnd, IDC_SLIDER2, TBM_SETRANGE, 0, MAKELONG(DENSITY_MIN, DENSITY_MAX));
SendDlgItemMessage(hwnd, IDC_SLIDER3, TBM_SETRANGE, 0, MAKELONG(MSGSPEED_MIN, MSGSPEED_MAX));
SendDlgItemMessage(hwnd, IDC_SLIDER4, TBM_SETRANGE, 0, MAKELONG(FONT_MIN, FONT_MAX));
//SendDlgItemMessage(hwnd, IDC_SLIDER1, TBM_SETTICFREQ, 5, 0);
SendDlgItemMessage(hwnd, IDC_SLIDER2, TBM_SETTICFREQ, 5, 0);
SendDlgItemMessage(hwnd, IDC_SLIDER3, TBM_SETTICFREQ, 50, 0);
SendDlgItemMessage(hwnd, IDC_SLIDER4, TBM_SETTICFREQ, 2, 0);
SendDlgItemMessage(hwnd, IDC_SLIDER1, TBM_SETPOS, TRUE, g_nMatrixSpeed);
SendDlgItemMessage(hwnd, IDC_SLIDER2, TBM_SETPOS, TRUE, g_nDensity);
SendDlgItemMessage(hwnd, IDC_SLIDER3, TBM_SETPOS, TRUE, g_nMessageSpeed);
SendDlgItemMessage(hwnd, IDC_SLIDER4, TBM_SETPOS, TRUE, g_nFontSize);
CheckDlgButton(hwnd, IDC_RANDOM, g_fRandomizeMessages);
CheckDlgButton(hwnd, IDC_BOLD, g_fFontBold);
AddFonts(GetDlgItem(hwnd, IDC_COMBO2));
index = SendDlgItemMessage(hwnd, IDC_COMBO2, CB_FINDSTRING, 0, (LPARAM)g_szFontName);
SendDlgItemMessage(hwnd, IDC_COMBO2, CB_SETCURSEL, index, 0);
UpdatePreview(hwnd);
return 0;
case WM_DESTROY:
//DeInitMessage();
return 0;
case WM_CTLCOLORSTATIC:
if(GetDlgCtrlID((HWND)lParam) == IDC_ABOUT)
{
SetTextColor((HDC)wParam, RGB(0,80,0));
SetBkColor((HDC)wParam, GetSysColor(COLOR_3DFACE));
return (BOOL)GetSysColorBrush(COLOR_3DFACE);
}
else if(GetDlgCtrlID((HWND)lParam) == IDC_PREVIEW)
{
HDC hdc = (HDC)wParam;
RECT clip;
GetDlgItemText(hwnd, IDC_COMBO1, buf, 256);
GetClientRect((HWND)lParam, &rect);
if(prevwidth < rect.right)
{
rect.left = (rect.right-prevwidth) / 2;
rect.right = rect.left + prevwidth;
}
else
{
rect.left = 0;
rect.right = prevwidth;
}
if(prevheight < rect.bottom)
{
rect.top = (rect.bottom-prevheight) / 2;
rect.bottom = rect.top + prevheight;
}
else
{
rect.top = 0;
rect.bottom = prevheight;
}
SetTextColor(hdc, RGB(128,255,128));
SetBkColor(hdc, 0);
//SetRect(&rect, 0, 0, PrevMessage->width, MAXMSG_HEIGHT);
CopyRect(&clip, &rect);
FillRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
SelectObject(hdc, g_hFont);
InflateRect(&clip, 2, 2);
FrameRect(hdc, &clip, GetSysColorBrush(COLOR_3DSHADOW));
IntersectClipRect(hdc, rect.left, rect.top, rect.right, rect.bottom);
// figure out where the bounding rectangle should be
DrawText(hdc, buf, -1, &rect, DT_CENTER|DT_VCENTER|DT_WORDBREAK|DT_CALCRECT);
OffsetRect(&rect, (prevwidth-(rect.right-rect.left))/2, (prevheight-(rect.bottom-rect.top))/2);
// now draw it!
DrawText(hdc, buf, -1, &rect, DT_CENTER|DT_VCENTER|DT_WORDBREAK);
return (BOOL)GetStockObject(NULL_BRUSH);
}
else
{
break;
}
case WM_HSCROLL:
if((HWND)lParam == GetDlgItem(hwnd, IDC_SLIDER4))
{
// one of the sliders changed..update
UpdatePreview(hwnd);
}
return 0;
case WM_COMMAND:
switch(HIWORD(wParam))
{
case CBN_EDITCHANGE:
case CBN_SELCHANGE:
//fall through to Preview:
index = SendDlgItemMessage(hwnd, IDC_COMBO2, CB_GETCURSEL, 0, 0);
SendDlgItemMessage(hwnd, IDC_COMBO2, CB_GETLBTEXT, index, (LPARAM)g_szFontName);
//SetMessageFont(hwnd, g_szFontName, g_nFontSize, TRUE);
UpdatePreview(hwnd);
return 0;
}
switch(LOWORD(wParam))
{
case IDC_RANDOM:
g_fRandomizeMessages = IsDlgButtonChecked(hwnd, IDC_RANDOM);
break;
case IDC_BOLD:
g_fFontBold = IsDlgButtonChecked(hwnd, IDC_BOLD);
UpdatePreview(hwnd);
break;
case IDOK:
hwndCtrl = GetDlgItem(hwnd, IDC_COMBO1);
items = min(MAX_MESSAGES, SendMessage(hwndCtrl, CB_GETCOUNT, 0, 0));
for(index = 0; index < items; index++)
{
SendMessage(hwndCtrl, CB_GETLBTEXT, index, (LPARAM)g_szMessages[index]);
}
g_nNumMessages = items;
//matrix speed
val = SendDlgItemMessage(hwnd, IDC_SLIDER1, TBM_GETPOS, 0, 0);
if(val >= SPEED_MIN && val <= SPEED_MAX)
g_nMatrixSpeed = val;
//density
val = SendDlgItemMessage(hwnd, IDC_SLIDER2, TBM_GETPOS, 0, 0);
if(val >= DENSITY_MIN && val <= DENSITY_MAX)
g_nDensity = val;
//message speed
val = SendDlgItemMessage(hwnd, IDC_SLIDER3, TBM_GETPOS, 0, 0);
if(val >= MSGSPEED_MIN && val <= MSGSPEED_MAX)
g_nMessageSpeed = val;
//font size
val = SendDlgItemMessage(hwnd, IDC_SLIDER4, TBM_GETPOS, 0, 0);
if(val >= FONT_MIN && val <= FONT_MAX)
g_nFontSize = val;
SaveSettings();
EndDialog(hwnd, 0);
return 0;
case IDCANCEL:
EndDialog(hwnd, 0);
return TRUE;
case IDC_ADD:
hwndCombo = GetDlgItem(hwnd, IDC_COMBO1);
if(GetWindowText(hwndCombo, buf, 256))
{
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)buf);
}
UpdatePreview(hwnd);
return 0;
case IDC_REMOVE:
hwndCombo = GetDlgItem(hwnd, IDC_COMBO1);
GetWindowText(hwndCombo, buf, 256);
index = SendMessage(hwndCombo, CB_GETCURSEL, 0, 0);
SendMessage(hwndCombo, CB_DELETESTRING, index, 0);
SendMessage(hwndCombo, CB_SETCURSEL, 0, 0);
UpdatePreview(hwnd);
return 0;
}
return 0;
case WM_CLOSE:
EndDialog(hwnd, 0);
return 0;
}
return 0;
}
//
// Display the configuration dialog
//
int Configure(HWND hwndParent)
{
INITCOMMONCONTROLSEX icc;
icc.dwICC = ICC_UPDOWN_CLASS | ICC_BAR_CLASSES;
icc.dwSize = sizeof(icc);
InitCommonControlsEx(&icc);
#ifdef _DEBUG
if(hwndParent == NULL)
hwndParent = 0;
#else
if(hwndParent == NULL)
hwndParent = GetForegroundWindow();
#endif
DialogBox(GetModuleHandle(0), MAKEINTRESOURCE(IDD_CONFIG), hwndParent, ConfigDlgProc);
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

View file

@ -0,0 +1,63 @@
#ifndef GLOBALS_INCLUDED
#define GLOBALS_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
#define APPNAME "MATRIX ScreenSaver 2.0"
#define DENSITY 24
#define DENSITY_MAX 50
#define DENSITY_MIN 5
// constants inferred from matrix.bmp
#define MAX_INTENSITY 5 // number of intensity levels
#define NUM_GLYPHS 26 // number of "glyphs" in each level
#define GLYPH_WIDTH 14 // width of each glyph (pixels)
#define GLYPH_HEIGHT 14 // height of each glyph (pixels)
#define SPEED_MAX 10
#define SPEED_MIN 1
#define MAXMSG_WIDTH 0x100
#define MAXMSG_HEIGHT 0x100
#define MAXMSG_LENGTH 64
#define MSGSPEED_MAX 500
#define MSGSPEED_MIN 50
#define MAX_MESSAGES 16
#define FONT_MIN 8
#define FONT_MAX 30
extern char g_szMessages[MAX_MESSAGES][MAXMSG_LENGTH];
extern int g_nFontSize;
extern char g_szFontName[];
extern BOOL g_fFontBold;
extern int g_nNumMessages;
extern int g_nCurrentMessage;
extern int g_nMessageSpeed;
extern int g_nMatrixSpeed;
extern int g_nDensity;
extern BOOL g_fRandomizeMessages;
extern HFONT g_hFont;
extern BOOL g_fScreenSaving;
void LoadSettings();
void SaveSettings();
BOOL ChangePassword(HWND hwnd);
BOOL VerifyPassword(HWND hwnd);
BOOL Configure(HWND hwndParent);
BOOL ScreenSaver(HWND hwndParent);
int crc_rand();
#ifdef __cplusplus
}
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -0,0 +1,445 @@
//
// matrix.c
//
// Matrix-window implementation
//
#include <windows.h>
#include <windowsx.h>
#include "globals.h"
#include "message.h"
#include "matrix.h"
#include "resource.h"
void DoMatrixMessage(HDC hdc, MATRIX *matrix);
// pseudo-random number generator, based on 16bit CRC algorithm
static WORD _crc_reg = 0;
int crc_rand()
{
const WORD mask = 0xb400;
if(_crc_reg & 1)
_crc_reg = (_crc_reg >> 1) ^ mask;
else
_crc_reg = (_crc_reg >> 1);
return _crc_reg;
}
int GlyphIntensity(GLYPH glyph)
{
return (int)((glyph & 0x7f00) >> 8);
}
GLYPH DarkenGlyph(GLYPH glyph)
{
int intensity = GlyphIntensity(glyph);
if(intensity > 0)
return GLYPH_REDRAW | ((intensity - 1) << 8) | (glyph & 0x00FF);
else
return glyph;
}
GLYPH RandomGlyph(int intensity)
{
return GLYPH_REDRAW | (intensity << 8) | (crc_rand() % NUM_GLYPHS);
}
void RedrawBlip(GLYPH *glypharr, int blippos)
{
glypharr[blippos+0] |= GLYPH_REDRAW;
glypharr[blippos+1] |= GLYPH_REDRAW;
glypharr[blippos+8] |= GLYPH_REDRAW;
glypharr[blippos+9] |= GLYPH_REDRAW;
}
void ScrollMatrixColumn(MATRIX_COLUMN *col)
{
int y;
GLYPH lastglyph = 0;
GLYPH thisglyph;
// wait until we are allowed to scroll
if(col->started == FALSE)
{
if(--col->countdown <= 0)
col->started = TRUE;
return;
}
// "seed" the glyph-run
lastglyph = col->state ? (GLYPH)0 : (GLYPH)(MAX_INTENSITY << 8);
//
// loop over the entire length of the column, looking for changes
// in intensity/darkness. This change signifies the start/end
// of a run of glyphs.
//
for(y = 0; y < col->length; y++)
{
thisglyph = col->glyph[y];
// bottom-most part of "run". Insert a new character (glyph)
// at the end to lengthen the run down the screen..gives the
// impression that the run is "falling" down the screen
if(GlyphIntensity(thisglyph) < GlyphIntensity(lastglyph) &&
GlyphIntensity(thisglyph) == 0)
{
col->glyph[y] = RandomGlyph(MAX_INTENSITY - 1);
y++;
}
// top-most part of "run". Delete a character off the top by
// darkening the glyph until it eventually disappears (turns black).
// this gives the effect that the run as dropped downwards
else if(GlyphIntensity(thisglyph) > GlyphIntensity(lastglyph))
{
col->glyph[y] = DarkenGlyph(thisglyph);
// if we've just darkened the last bit, skip on so
// the whole run doesn't go dark
if(GlyphIntensity(thisglyph) == MAX_INTENSITY - 1)
y++;
}
lastglyph = col->glyph[y];
}
// change state from blanks <-> runs when the current run as expired
if(--col->runlen <= 0)
{
if(col->state ^= 1)
col->runlen = crc_rand() % (3 * DENSITY/2) + DENSITY_MIN;
else
col->runlen = crc_rand() % (DENSITY_MAX+1-DENSITY) + (DENSITY_MIN*2);
}
//
// make a "blip" run down this column at double-speed
//
// mark current blip as redraw so it gets "erased"
if(col->blippos >= 0 && col->blippos < col->length)
RedrawBlip(col->glyph, col->blippos);
// advance down screen at double-speed
col->blippos += 2;
// if the blip gets to the end of a run, start it again (for a random
// length so that the blips never get synched together)
if(col->blippos >= col->bliplen)
{
col->bliplen = col->length + crc_rand() % 50;
col->blippos = 0;
}
// now redraw blip at new position
if(col->blippos >= 0 && col->blippos < col->length)
RedrawBlip(col->glyph, col->blippos);
}
//
// randomly change a small collection glyphs in a column
//
void RandomMatrixColumn(MATRIX_COLUMN *col)
{
int i, y;
for(i = 1, y = 0; i < 16; i++)
{
// find a run
while(GlyphIntensity(col->glyph[y]) < MAX_INTENSITY-1 && y < col->length)
y++;
if(y >= col->length)
break;
col->glyph[y] = (col->glyph[y] & 0xff00) | (crc_rand() % NUM_GLYPHS);
col->glyph[y] |= GLYPH_REDRAW;
y += crc_rand() % 10;
}
}
void DrawGlyph(MATRIX *matrix, HDC hdc, int xpos, int ypos, GLYPH glyph)
{
int intensity = GlyphIntensity(glyph);
int glyphidx = glyph & 0xff;
BitBlt(hdc, xpos, ypos, GLYPH_WIDTH, GLYPH_HEIGHT, matrix->hdcBitmap,
glyphidx * GLYPH_WIDTH, intensity * GLYPH_HEIGHT, SRCCOPY);
}
void RedrawMatrixColumn(MATRIX_COLUMN *col, MATRIX *matrix, HDC hdc, int xpos)
{
int y;
// loop down the length of the column redrawing only what needs doing
for(y = 0; y < col->length; y++)
{
GLYPH glyph = col->glyph[y];
// does this glyph (character) need to be redrawn?
if(glyph & GLYPH_REDRAW)
{
if((y == col->blippos+0 || y == col->blippos+1 ||
y == col->blippos+8 || y == col->blippos+9) &&
GlyphIntensity(glyph) >= MAX_INTENSITY-1)
glyph |= MAX_INTENSITY << 8;
DrawGlyph(matrix, hdc, xpos, y * GLYPH_HEIGHT, glyph);
// clear redraw state
col->glyph[y] &= ~GLYPH_REDRAW;
}
}
}
void DecodeMatrix(HWND hwnd, MATRIX *matrix)
{
int x;
HDC hdc = GetDC(hwnd);
for(x = 0; x < matrix->numcols; x++)
{
RandomMatrixColumn(&matrix->column[x]);
ScrollMatrixColumn(&matrix->column[x]);
RedrawMatrixColumn(&matrix->column[x], matrix, hdc, x * GLYPH_WIDTH);
}
if(matrix->message)
DoMatrixMessage(hdc, matrix);
ReleaseDC(hwnd, hdc);
}
//
// Allocate matrix structures
//
MATRIX *CreateMatrix(HWND hwnd, int width, int height)
{
MATRIX *matrix;
HDC hdc;
int x, y;
int rows = height / GLYPH_HEIGHT + 1;
int cols = width / GLYPH_WIDTH + 1;
// allocate matrix!
if((matrix = malloc(sizeof(MATRIX) + sizeof(MATRIX_COLUMN) * cols)) == 0)
return 0;
matrix->numcols = cols;
matrix->numrows = rows;
matrix->width = width;
matrix->height = height;
for(x = 0; x < cols; x++)
{
matrix->column[x].length = rows;
matrix->column[x].started = FALSE;
matrix->column[x].countdown = crc_rand() % 100;
matrix->column[x].state = crc_rand() % 2;
matrix->column[x].runlen = crc_rand() % 20 + 3;
matrix->column[x].glyph = malloc(sizeof(GLYPH) * (rows+16));
for(y = 0; y < rows; y++)
matrix->column[x].glyph[y] = 0;//;
}
// Load bitmap!!
hdc = GetDC(NULL);
matrix->hbmBitmap = LoadBitmap(GetModuleHandle(0), MAKEINTRESOURCE(IDB_BITMAP1));
matrix->hdcBitmap = CreateCompatibleDC(hdc);
SelectObject(matrix->hdcBitmap, matrix->hbmBitmap);
ReleaseDC(NULL, hdc);
// Create a message for this window...only if we are
// screen-saving (not if in preview mode)
if(GetParent(hwnd) == 0)
matrix->message = InitMatrixMessage(hwnd, matrix->numcols, matrix->numrows);
else
matrix->message = 0;
return matrix;
}
//
// Free up matrix structures
//
void DestroyMatrix(MATRIX *matrix)
{
int x;
// free the matrix columns
for(x = 0; x < matrix->numcols; x++)
free(matrix->column[x].glyph);
DeleteDC(matrix->hdcBitmap);
DeleteObject(matrix->hbmBitmap);
// now delete the matrix!
free(matrix);
}
MATRIX *GetMatrix(HWND hwnd)
{
return (MATRIX *)GetWindowLong(hwnd, 0);
}
void SetMatrix(HWND hwnd, MATRIX *matrix)
{
SetWindowLong(hwnd, 0, (LONG)matrix);
}
//
// Window procedure for one matrix (1 per screen)
//
LRESULT WINAPI MatrixWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static POINT ptLast;
static POINT ptCursor;
static BOOL fFirstTime = TRUE;
MATRIX *matrix = GetMatrix(hwnd);
switch(msg)
{
// window creation
case WM_NCCREATE:
// create the matrix based on how big this window is
matrix = CreateMatrix(hwnd, ((CREATESTRUCT *)lParam)->cx, ((CREATESTRUCT *)lParam)->cy);
// failed to allocate? stop window creation!
if(matrix == 0)
return FALSE;
SetMatrix(hwnd, matrix);
// start off an animation timer
SetTimer(hwnd, 0xdeadbeef, ((SPEED_MAX - g_nMatrixSpeed) + SPEED_MIN) * 10, 0);
return TRUE;
// window being destroyed, cleanup
case WM_NCDESTROY:
DestroyMatrix(matrix);
PostQuitMessage(0);
return 0;
// animation timer has gone off, redraw the matrix!
case WM_TIMER:
DecodeMatrix(hwnd, matrix);
return 0;
// break out of screen-saver if any keyboard activity
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
PostMessage(hwnd, WM_CLOSE, 0, 0);
return 0;
// break out of screen-saver if any mouse activity
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_MOUSEMOVE:
// If we've got a parent then we must be a preview
if(GetParent(hwnd) != 0)
return 0;
if(fFirstTime)
{
GetCursorPos(&ptLast);
fFirstTime = FALSE;
}
GetCursorPos(&ptCursor);
// if the mouse has moved more than 3 pixels then exit
if(abs(ptCursor.x - ptLast.x) >= 3 || abs(ptCursor.y - ptLast.y) >= 3)
PostMessage(hwnd, WM_CLOSE, 0, 0);
ptLast = ptCursor;
return 0;
// someone wants to close us...see if it's ok
case WM_CLOSE:
if(VerifyPassword(hwnd))
{
KillTimer(hwnd, 0xdeadbeef);
DestroyWindow(hwnd);
}
return 0;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
HWND CreateScreenSaveWnd(HWND hwndParent, RECT *rect)
{
DWORD dwStyle = hwndParent ? WS_CHILD : WS_POPUP;
#ifdef _DEBUG
DWORD dwStyleEx = 0;
#else
DWORD dwStyleEx = WS_EX_TOPMOST;
#endif
if(hwndParent)
GetClientRect(hwndParent, rect);
return CreateWindowEx( dwStyleEx,
APPNAME,
0,
WS_VISIBLE | dwStyle,
rect->left,
rect->top,
rect->right - rect->left,
rect->bottom - rect->top,
hwndParent,
0,
GetModuleHandle(0),
0
);
}
//
// Initialize class for matrix window
//
void InitScreenSaveClass(BOOL fPreview)
{
WNDCLASSEX wcx;
wcx.cbSize = sizeof(WNDCLASSEX);
wcx.style = 0;
wcx.lpfnWndProc = MatrixWndProc;
wcx.cbClsExtra = 0;
wcx.cbWndExtra = sizeof(MATRIX *);
wcx.hInstance = GetModuleHandle(0);
wcx.hIcon = 0;
wcx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcx.lpszMenuName = 0;
wcx.lpszClassName = APPNAME;
wcx.hIconSm = 0;
if(fPreview)
wcx.hCursor = LoadCursor(0, IDC_ARROW);
else
wcx.hCursor = LoadCursor(wcx.hInstance, MAKEINTRESOURCE(IDC_BLANKCURSOR));
// initialize the crc register used for "random" number generation
_crc_reg = (WORD)GetTickCount();
RegisterClassEx(&wcx);
}

View file

@ -0,0 +1,158 @@
# Microsoft Developer Studio Project File - Name="matrix" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=matrix - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "matrix.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "matrix.mak" CFG="matrix - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "matrix - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "matrix - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "matrix - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX- /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 libctiny.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /map /debug /machine:I386
!ELSEIF "$(CFG)" == "matrix - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "matrix - Win32 Release"
# Name "matrix - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\config.c
# End Source File
# Begin Source File
SOURCE=.\matrix.c
# End Source File
# Begin Source File
SOURCE=.\matrix.rc
# End Source File
# Begin Source File
SOURCE=.\message.c
# End Source File
# Begin Source File
SOURCE=.\password.c
# End Source File
# Begin Source File
SOURCE=.\screensave.c
# End Source File
# Begin Source File
SOURCE=.\settings.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\globals.h
# End Source File
# Begin Source File
SOURCE=.\matrix.h
# End Source File
# Begin Source File
SOURCE=.\message.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\cursor1.cur
# End Source File
# Begin Source File
SOURCE=.\icon1.ico
# End Source File
# Begin Source File
SOURCE=.\matrix.bmp
# End Source File
# Begin Source File
SOURCE=.\matrix2.bmp
# End Source File
# End Group
# End Target
# End Project

View file

@ -0,0 +1,70 @@
#ifndef MATRIX_INCLUDED
#define MATRIX_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
//
// Top BYTE of each glyph is used as flags
// (redraw state, intensity etc)
//
// Bottom BYTE of each glyph is the character value
//
// Bit: 15 14 13-8 | 7-0
//
// [Redraw][Blank][Intensity] [Glyph]
//
typedef unsigned short GLYPH;
#define GLYPH_REDRAW 0x8000
#define GLYPH_BLANK 0x4000
//
// The "matrix" is basically an array of these
// column structures, positioned side-by-side
//
typedef struct
{
BOOL state;
int countdown;
BOOL started;
int runlen;
int blippos;
int bliplen;
int length;
GLYPH *glyph;
} MATRIX_COLUMN;
typedef struct
{
int width;
int height;
int numcols;
int numrows;
// bitmap containing glyphs.
HDC hdcBitmap;
HBITMAP hbmBitmap;
MATRIX_MESSAGE *message;
MATRIX_COLUMN column[1];
} MATRIX;
GLYPH RandomGlyph(int intensity);
void DrawGlyph(MATRIX *matrix, HDC hdc, int xpos, int ypos, GLYPH glyph);
HWND CreateScreenSaveWnd(HWND hwndParent, RECT *rect);
void InitScreenSaveClass();
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,34 @@
<?xml version="1.0"?>
<!DOCTYPE project SYSTEM "tools/rbuild/project.dtd">
<module name="matrix" type="win32scr" installbase="system32" installname="matrix2.scr" allowwarnings="true">
<include base="matrix">.</include>
<linkerflag>-lstdc++</linkerflag>
<define name="__USE_W32API" />
<define name="_WIN32_IE">0x0501</define>
<define name="_WIN32_WINNT">0x0501</define>
<define name="__REACTOS__" />
<library>kernel32</library>
<library>user32</library>
<library>gdi32</library>
<library>winspool</library>
<library>comctl32</library>
<library>comdlg32</library>
<library>advapi32</library>
<library>shell32</library>
<library>ole32</library>
<library>oleaut32</library>
<library>uuid</library>
<file>config.c</file>
<file>matrix.c</file>
<file>message.c</file>
<file>password.c</file>
<file>screensave.c</file>
<file>settings.c</file>
<file>matrix.rc</file>
</module>

View file

@ -0,0 +1,167 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_CONFIG DIALOG DISCARDABLE 0, 0, 340, 183
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Matrix ScreenSaver Configuration"
FONT 8, "MS Sans Serif"
BEGIN
GROUPBOX "Decode &Speed",IDC_STATIC,7,7,128,36
LTEXT "Slower",IDC_STATIC,13,24,22,8
CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS |
TBS_BOTH | WS_TABSTOP,38,17,62,22
LTEXT "Faster",IDC_STATIC,104,24,20,8
GROUPBOX "Cypher &Density",IDC_STATIC,7,50,128,36
LTEXT "Less",IDC_STATIC,13,67,19,8
CONTROL "Slider1",IDC_SLIDER2,"msctls_trackbar32",TBS_AUTOTICKS |
TBS_BOTH | WS_TABSTOP,38,60,62,22
LTEXT "More",IDC_STATIC,104,67,23,8
GROUPBOX "&Message Display Speed",IDC_MSGSPEEDGRP,7,93,127,36
LTEXT "Slower",IDC_STATIC,13,110,22,8
CONTROL "Slider3",IDC_SLIDER3,"msctls_trackbar32",TBS_AUTOTICKS |
TBS_BOTH | WS_TABSTOP,38,103,62,22
LTEXT "Faster",IDC_STATIC,104,110,22,8
GROUPBOX "&Font Size",IDC_STATIC,7,137,127,36
LTEXT "Smaller",IDC_STATIC,13,153,24,8
CONTROL "Slider3",IDC_SLIDER4,"msctls_trackbar32",TBS_AUTOTICKS |
TBS_BOTH | WS_TABSTOP,38,146,62,22
LTEXT "Bigger",IDC_STATIC,104,153,25,8
GROUPBOX "Coded Messages",IDC_STATIC,145,7,188,142
COMBOBOX IDC_COMBO1,153,22,172,62,CBS_DROPDOWN | WS_VSCROLL |
WS_TABSTOP
CONTROL "",IDC_PREVIEW,"Static",SS_LEFTNOWORDWRAP |
SS_CENTERIMAGE | WS_GROUP,154,39,116,72
PUSHBUTTON "&Add",IDC_ADD,280,41,44,18
PUSHBUTTON "&Remove",IDC_REMOVE,280,66,44,18
CONTROL "Randomize Messages",IDC_RANDOM,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,151,134,85,10
DEFPUSHBUTTON "OK",IDOK,222,162,50,14
PUSHBUTTON "Cancel",IDCANCEL,283,162,50,14
COMBOBOX IDC_COMBO2,195,116,130,71,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
LTEXT "&Font Name:",IDC_STATIC,151,118,38,8
CONTROL "&Bold Font",IDC_BOLD,"Button",BS_AUTOCHECKBOX |
BS_MULTILINE | WS_TABSTOP,247,134,46,10
CTEXT "Matrix ScreenSaver www.catch22.org.uk",IDC_ABOUT,140,
158,75,18
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_CONFIG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 333
TOPMARGIN, 7
BOTTOMMARGIN, 176
END
END
#endif // APSTUDIO_INVOKED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_BITMAP1 BITMAP DISCARDABLE "matrix.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Cursor
//
IDC_BLANKCURSOR CURSOR DISCARDABLE "cursor1.cur"
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "icon1.ico"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_DESCRIPTION "Matrix ScreenSaver"
END
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View file

@ -0,0 +1,250 @@
//
// message.c
//
// Dissolve in/out messages into the "matrix"
//
//
//
#include <windows.h>
#include "globals.h"
#include "message.h"
#include "matrix.h"
//
// this isn't really a random-number generator. It's based on
// a 16bit CRC algorithm. With the right mask (0xb400) it is possible
// to call this function 65536 times and get a unique result every time
// with *NO* repeats. The results look random but they're not - if we
// call this function another 65536 times we get exactly the same results
// in the same order. This is necessary for fading in messages because
// we need to be guaranteed that all cells...it's completely uniform in
// operation but looks random enough to be very effective
//
WORD crc_msgrand(WORD reg)
{
const WORD mask = 0xb400;
if(reg & 1)
reg = (reg >> 1) ^ mask;
else
reg = (reg >> 1);
return reg;
}
//
// Set a new message based on font and text
//
void SetMatrixMessage(MATRIX_MESSAGE *msg, HFONT hFont, char *text)
{
HDC hdc;
RECT rect;
int x, y;
HDC hdcMessage;
HBITMAP hbmMessage;
HANDLE hOldFont, hOldBmp;
//
// Create a monochrome off-screen buffer
//
hdc = GetDC(NULL);
hdcMessage = CreateCompatibleDC(hdc);
hbmMessage = CreateBitmap(MAXMSG_WIDTH, MAXMSG_HEIGHT, 1, 1, 0);
hOldBmp = SelectObject(hdcMessage, hbmMessage);
ReleaseDC(NULL, hdc);
//
// Draw text into bitmap
//
SetRect(&rect, 0, 0, msg->width, MAXMSG_HEIGHT);
FillRect(hdcMessage, &rect, GetStockObject(WHITE_BRUSH));
hOldFont = SelectObject(hdcMessage, g_hFont);
DrawText(hdcMessage, text, -1, &rect, DT_CENTER|DT_VCENTER|DT_WORDBREAK|DT_CALCRECT);
OffsetRect(&rect, (msg->width-(rect.right-rect.left))/2, (msg->height-(rect.bottom-rect.top))/2);
DrawText(hdcMessage, text, -1, &rect, DT_CENTER|DT_VCENTER|DT_WORDBREAK);
//
// Convert bitmap into an array of cells for easy drawing
//
for(y = 0; y < msg->height; y++)
{
for(x = 0; x < msg->width; x++)
{
msg->message[x][y] = GetPixel(hdcMessage, x, y) ? 0 : 1;
}
}
//
// Cleanup
//
SelectObject(hdcMessage, hOldFont);
SelectObject(hdcMessage, hOldBmp);
DeleteDC(hdcMessage);
DeleteObject(hbmMessage);
}
//
// Draw any part of the message that is visible. Make the
// message "shimmer" by using a random glyph each time
//
void DrawMatrixMessage(MATRIX *matrix, MATRIX_MESSAGE *msg, HDC hdc)
{
int x, y;
for(x = 0; x < msg->width; x++)
for(y = 0; y < msg->height; y++)
if((msg->message[x][y] & 0x8000) &&
(msg->message[x][y] & 0x00FF))
{
DrawGlyph(matrix, hdc, x * GLYPH_WIDTH, y * GLYPH_HEIGHT, RandomGlyph(MAX_INTENSITY));
}
}
//
// Reveal specified amount of message
//
void RevealMatrixMessage(MATRIX_MESSAGE *msg, int amount)
{
while(amount--)
{
int pos;
msg->random_reg1 = crc_msgrand(msg->random_reg1);
pos = msg->random_reg1 & 0xffff;
msg->message[pos / 256][pos % 256] |= GLYPH_REDRAW;
}
}
//
// Reset (hide) the message
//
void ClearMatrixMessage(MATRIX_MESSAGE *msg)
{
int x, y;
for(x = 0; x < msg->width; x++)
for(y = 0; y < msg->height; y++)
msg->message[x][y] = 0;
}
//
// convert from 50-500 (fast-slow) to slow(50) - fast(500)
//
int MessageSpeed()
{
return (MSGSPEED_MAX-MSGSPEED_MIN) - (g_nMessageSpeed-MSGSPEED_MIN) + MSGSPEED_MIN;
}
//
// Called once for each iteration of the matrix
//
void DoMatrixMessage(HDC hdc, MATRIX *matrix)
{
MATRIX_MESSAGE *msg = matrix->message;
int RealSpeed = MessageSpeed();
if(g_nNumMessages > 0)
{
// nothing to do yet..
if(msg->counter++ < 0)
return;
// has counter reached limit..clear the message
if(msg->counter++ == RealSpeed / 2 + (RealSpeed/4))
ClearMatrixMessage(msg);
// reset counter + display a new message
if(msg->counter >= RealSpeed)
{
// mark all message-cells as being "invisible" so the
// message gets cleared by the matrix decoding naturally
if(g_fRandomizeMessages)
msg->msgindex = crc_rand() % g_nNumMessages;
else
msg->msgindex = (msg->msgindex + 1) % g_nNumMessages;
// make a new message..initially invisible
SetMatrixMessage(msg, 0, g_szMessages[msg->msgindex]);
msg->counter = -(int)(crc_rand() % MSGSPEED_MAX);
}
// reveal the next part of the message
else if(msg->counter < RealSpeed / 2)
{
int w = (g_nMessageSpeed - MSGSPEED_MIN);
w = (1 << 16) + ((w<<16) / MSGSPEED_MAX);
w = (w * 3 * g_nMessageSpeed) >> 16;
RevealMatrixMessage(msg, w + 100);
}
//
// draw whatever part of the message is visible at this time
//
DrawMatrixMessage(matrix, msg, hdc);
}
}
//
// Set current font used for messages
//
void SetMessageFont(HWND hwnd, char *szFontName, int nPointSize, BOOL fBold)
{
int lfHeight;
HDC hdc;
HFONT hFont;
hdc = GetDC(hwnd);
lfHeight = -MulDiv(nPointSize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
ReleaseDC(hwnd, hdc);
hFont = CreateFont(lfHeight, 0, 0, 0, fBold ? FW_BOLD: FW_NORMAL, 0, 0, 0,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY, DEFAULT_PITCH, szFontName);
if(hFont != 0)
{
if(g_hFont != 0)
DeleteObject(g_hFont);
g_hFont = hFont;
}
}
//
// Create a message!
//
MATRIX_MESSAGE *InitMatrixMessage(HWND hwnd, int width, int height)
{
MATRIX_MESSAGE *msg;
if((msg = malloc(sizeof(MATRIX_MESSAGE))) == 0)
return 0;
ClearMatrixMessage(msg);
msg->msgindex = 0;
msg->width = min(width, MAXMSG_WIDTH);
msg->height = min(height, MAXMSG_HEIGHT);
msg->counter = -(int)(crc_rand() % MSGSPEED_MIN + MSGSPEED_MIN);
msg->random_reg1 = (WORD)GetTickCount();
SetMessageFont(hwnd, g_szFontName, g_nFontSize, g_fFontBold);
SetMatrixMessage(msg, 0, g_szMessages[0]);
return msg;
}

View file

@ -0,0 +1,32 @@
#ifndef MESSAGE_INCLUDED
#define MESSAGE_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
//
// counter starts off negative (rand() < 0)..when it gets
// to zero the message starts to display
//
typedef struct
{
WORD message[MAXMSG_WIDTH][MAXMSG_HEIGHT];
int msgindex;
int counter;
WORD random_reg1;
int width, height;
} MATRIX_MESSAGE;
void SetMessageFont(HWND hwnd, char *szFontName, int nPointSize, BOOL fBold);
MATRIX_MESSAGE *InitMatrixMessage(HWND hwnd, int width, int height);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,68 @@
//
// password.c
//
// Password support for Win9x
//
#include <windows.h>
typedef BOOL (WINAPI *VERIFYSCREENSAVEPWD)(HWND hwnd);
typedef VOID (WINAPI *PWDCHANGEPASSWORD)(LPCSTR lpcRegkeyname, HWND hwnd,UINT uiReserved1,UINT uiReserved2);
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
HINSTANCE hpwdcpl;
VERIFYSCREENSAVEPWD VerifyScreenSavePwd;
BOOL fResult;
if(GetVersion() < 0x80000000)
return TRUE;
hpwdcpl = LoadLibrary("PASSWORD.CPL");
if(hpwdcpl == NULL)
{
return FALSE;
}
VerifyScreenSavePwd = (VERIFYSCREENSAVEPWD)GetProcAddress(hpwdcpl, "VerifyScreenSavePwd");
if(VerifyScreenSavePwd == NULL)
{
FreeLibrary(hpwdcpl);
return FALSE;
}
fResult = VerifyScreenSavePwd(hwnd);
FreeLibrary(hpwdcpl);
return fResult;
}
BOOL ChangePassword(HWND hwnd)
{
// This only ever gets called under '95, when started with the /a option.
HINSTANCE hmpr = LoadLibrary("MPR.DLL");
PWDCHANGEPASSWORD PwdChangePassword;
if(hmpr == NULL)
return FALSE;
PwdChangePassword = (PWDCHANGEPASSWORD)GetProcAddress(hmpr, "PwdChangePasswordA");
if(PwdChangePassword == NULL)
{
FreeLibrary(hmpr);
return FALSE;
}
PwdChangePassword("SCRSAVE", hwnd, 0, 0);
FreeLibrary(hmpr);
return TRUE;
}

View file

@ -0,0 +1,35 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by matrix.rc
//
#define IDS_DESCRIPTION 1
#define IDD_CONFIG 101
#define IDB_BITMAP1 104
#define IDC_BLANKCURSOR 105
#define IDI_ICON1 106
#define IDC_COMBO1 1003
#define IDC_REMOVE 1004
#define IDC_ADD 1005
#define IDC_PREVIEW 1008
#define IDC_PREV 1009
#define IDC_ENABLEPREV 1013
#define IDC_RANDOM 1014
#define IDC_SLIDER1 1015
#define IDC_SLIDER2 1016
#define IDC_SLIDER3 1017
#define IDC_SLIDER4 1018
#define IDC_BOLD 1019
#define IDC_COMBO2 1020
#define IDC_MSGSPEEDGRP 1021
#define IDC_ABOUT 1022
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1023
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View file

@ -0,0 +1,161 @@
//
// screensave.c
//
// Entrypoint for a win32 screensaver
//
// NOTES: Screen savers don't like being UPX'd (compressed). Don't
// know why, it just is. C-runtime has been stripped with
// "libctiny.lib".
//
// v1.0 1/12/2003 J Brown
//
#include <windows.h>
#include <windowsx.h>
#include "globals.h"
#include "message.h"
#include "matrix.h"
#include "resource.h"
#pragma comment(lib, "libctiny.lib")
#pragma comment(linker, "/OPT:NOWIN98")
//
// Added: Multimonitor support!!
//
HMONITOR (WINAPI * pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
BOOL (WINAPI * pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO);
//
// Callback function for EnumDisplayMonitors API. Use this function
// to kickstart a screen-saver window for each monitor in the system
//
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, RECT *rcMonitor, LPARAM Param)
{
HWND hwnd;
// Create a screensaver on this monitor!
hwnd = CreateScreenSaveWnd((HWND)Param, rcMonitor);
// For some reason windows always places this window at 0,0...
// position it ourselves
SetWindowPos(hwnd, 0, rcMonitor->left, rcMonitor->top, 0, 0,
SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE|SWP_SHOWWINDOW);
return TRUE;
}
//
// Start screen saver!
//
BOOL ScreenSaver(HWND hwndParent)
{
HMODULE hUser32;
UINT nPreviousState;
MSG msg;
InitScreenSaveClass(hwndParent);
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, TRUE, &nPreviousState, 0);
// Dynamically locate API call from USER32 - not present in all versions
hUser32 = GetModuleHandle("USER32.DLL");
pfnEnumDisplayMonitors = (PVOID)GetProcAddress(hUser32, "EnumDisplayMonitors");
// If we're running Win2k+ then the API is available...so call it!
if(pfnEnumDisplayMonitors && hwndParent == 0)
{
pfnEnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0);
}
// Otherwise simulate by calling enum-proc manually
else
{
RECT rect;
rect.left = 0;
rect.right = GetSystemMetrics(SM_CXSCREEN);
rect.top = 0;
rect.bottom = GetSystemMetrics(SM_CYSCREEN);
MonitorEnumProc(NULL, NULL, &rect, (LPARAM)hwndParent);
}
// run message loop to handle all screen-saver windows
while(GetMessage(&msg, NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING, FALSE, &nPreviousState, 0);
return TRUE;
}
//
// Look for any options Windows has passed to us:
//
// -a <hwnd> (set password)
// -s (screensave)
// -p <hwnd> (preview)
// -c <hwnd> (configure)
//
BOOL ParseCommandLine(PSTR szCmdLine, int *chOption, HWND *hwndParent)
{
int ch = *szCmdLine++;
if(ch == '-' || ch == '/')
ch = *szCmdLine++;
if(ch >= 'A' && ch <= 'Z')
ch += 'a' - 'A'; //convert to lower case
*chOption = ch;
ch = *szCmdLine++;
if(ch == ':')
ch = *szCmdLine++;
while(ch == ' ' || ch == '\t')
ch = *szCmdLine++;
if(isdigit(ch))
{
unsigned int i = atoi(szCmdLine - 1);
*hwndParent = (HWND)i;
}
else
*hwndParent = NULL;
return TRUE;
}
//
// Entrypoint for screen-saver: it's just a normal win32 app!
//
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmdLine, int iCmdShow)
{
HWND hwndParent;
int chOption;
// Make sure that only 1 instance runs at a time -
// Win98 seems to want us to restart every 5 seconds!!
if(FindWindowEx(NULL, NULL, APPNAME, APPNAME))
{
return 0;
}
LoadSettings();
ParseCommandLine(lpCmdLine, &chOption, &hwndParent);
switch(chOption)
{
case 's': return ScreenSaver(NULL); // screen save
case 'p': return ScreenSaver(hwndParent); // preview in small window
case 'a': return ChangePassword(hwndParent); // ask for password
case 'c': return Configure(hwndParent); // configuration dialog
default: return Configure(hwndParent); // configuration dialog
}
return 0;
}

View file

@ -0,0 +1,158 @@
//
// settings.c
//
// Load/Save settings from registry
//
#include <windows.h>
#include "globals.h"
#include "message.h"
#include "matrix.h"
char g_szMessages[MAX_MESSAGES][MAXMSG_LENGTH];
int g_nNumMessages = 0;
int g_nMessageSpeed = 5;
char g_szFontName[512] = "Arial";
int g_nMatrixSpeed = 150;
int g_nDensity = 32;
int g_nFontSize = 12;
BOOL g_fRandomizeMessages = FALSE;
BOOL g_fFontBold = TRUE;
BOOL g_fScreenSaving = FALSE;
HFONT g_hFont;
void LoadSettings()
{
HKEY hkey;
LONG value;
ULONG len;
char *hugechar = malloc(4096);
char *hptr = hugechar;
if(hugechar == 0)
return;
hugechar[0] = '\0';
RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Catch22\\Matrix Screen Saver", 0,
"", 0, KEY_READ, NULL, &hkey, NULL);
len = sizeof value;
if(ERROR_SUCCESS == RegQueryValueEx(hkey, "MessageSpeed", 0, 0, (BYTE *)&value, &len))
{
if(value >= MSGSPEED_MIN && value <= MSGSPEED_MAX)
g_nMessageSpeed = value;
}
if(ERROR_SUCCESS == RegQueryValueEx(hkey, "MatrixSpeed", 0, 0, (BYTE *)&value, &len))
{
if(value >= SPEED_MIN && value <= SPEED_MAX)
g_nMatrixSpeed = value;
}
if(ERROR_SUCCESS == RegQueryValueEx(hkey, "Density", 0, 0, (BYTE *)&value, &len))
{
if(value >= DENSITY_MIN && value <= DENSITY_MAX)
g_nDensity = value;
}
if(ERROR_SUCCESS == RegQueryValueEx(hkey, "FontSize", 0, 0, (BYTE *)&value, &len))
{
if(value >= FONT_MIN && value <= FONT_MAX)
g_nFontSize = value;
}
if(ERROR_SUCCESS == RegQueryValueEx(hkey, "FontBold", 0, 0, (BYTE *)&value, &len))
g_fFontBold = (value == 0 ? FALSE : TRUE);
if(ERROR_SUCCESS == RegQueryValueEx(hkey, "Randomize", 0, 0, (BYTE *)&value, &len))
g_fRandomizeMessages = (value == 0 ? FALSE : TRUE);
len = 4096;
if(ERROR_SUCCESS == RegQueryValueEx(hkey, "FontName", 0, 0, (BYTE *)hugechar, &len))
{
if(len > 0)
lstrcpy(g_szFontName, hugechar);
else
lstrcpy(g_szFontName, "Arial");
}
len = 4096;
if(ERROR_SUCCESS == RegQueryValueEx(hkey, "Messages", 0, 0 , (BYTE *)hugechar, &len))
{
while(len > 0 && *hptr && isascii(*hptr))
{
if(lstrlen(hptr) > 0)
{
lstrcpyn(g_szMessages[g_nNumMessages], hptr, MAXMSG_LENGTH);
++g_nNumMessages;
hptr += lstrlen(hptr) + 1;
}
}
}
RegCloseKey(hkey);
free(hugechar);
}
void SaveSettings()
{
HKEY hkey;
char *hugechar = malloc(4096);
char *msgptr = hugechar;
int totallen = 0;
int i,len;
LONG value;
if(hugechar == 0)
return;
hugechar[0] = '\0';
msgptr = hugechar;
RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Catch22\\Matrix Screen Saver", 0,
"", 0, KEY_WRITE, NULL, &hkey, NULL);
value = g_nMessageSpeed;
RegSetValueEx(hkey, "MessageSpeed", 0, REG_DWORD, (BYTE *)&value, sizeof value);
value = g_nMatrixSpeed;
RegSetValueEx(hkey, "MatrixSpeed", 0, REG_DWORD, (BYTE *)&value, sizeof value);
value = g_nDensity;
RegSetValueEx(hkey, "Density", 0, REG_DWORD, (BYTE *)&value, sizeof value);
value = g_nFontSize;
RegSetValueEx(hkey, "FontSize", 0, REG_DWORD, (BYTE *)&value, sizeof value);
value = g_fRandomizeMessages;
RegSetValueEx(hkey, "Randomize", 0, REG_DWORD, (BYTE *)&value, sizeof value);
value = g_fFontBold;
RegSetValueEx(hkey, "FontBold", 0, REG_DWORD, (BYTE *)&value, sizeof value);
RegSetValueEx(hkey, "FontName", 0, REG_SZ, (BYTE *)g_szFontName, lstrlen(g_szFontName));
for(i = 0; i < g_nNumMessages; i++)
{
len = lstrlen(g_szMessages[i]);
if(len > 0 && totallen+len < 4096)
{
lstrcpyn(msgptr, g_szMessages[i], 4096-totallen);
totallen += len + 1;
msgptr += len + 1;
}
}
*msgptr = '\0';
totallen++;
RegSetValueEx(hkey, "Messages", 0, REG_MULTI_SZ, (BYTE *)hugechar, totallen);
RegCloseKey(hkey);
free(hugechar);
}