ReactOS 0.4.15-dev-7788-g1ad9096
matrix.c
Go to the documentation of this file.
1//
2// matrix.c
3//
4// Matrix-window implementation
5//
6#include <windows.h>
7#include <windowsx.h>
8#include <tchar.h>
9#include "globals.h"
10#include "message.h"
11#include "matrix.h"
12#include "resource.h"
13
15
16// pseudo-random number generator, based on 16bit CRC algorithm
17static WORD _crc_reg = 0;
19{
20 const WORD mask = 0xb400;
21
22 if(_crc_reg & 1)
23 _crc_reg = (_crc_reg >> 1) ^ mask;
24 else
25 _crc_reg = (_crc_reg >> 1);
26
27 return _crc_reg;
28}
29
31{
32 return (int)((glyph & 0x7f00) >> 8);
33}
34
36{
37 int intensity = GlyphIntensity(glyph);
38
39 if(intensity > 0)
40 return GLYPH_REDRAW | ((intensity - 1) << 8) | (glyph & 0x00FF);
41 else
42 return glyph;
43}
44
45GLYPH RandomGlyph(int intensity)
46{
47 return GLYPH_REDRAW | (intensity << 8) | (crc_rand() % NUM_GLYPHS);
48}
49
50void RedrawBlip(GLYPH *glypharr, int blippos)
51{
52 glypharr[blippos+0] |= GLYPH_REDRAW;
53 glypharr[blippos+1] |= GLYPH_REDRAW;
54 glypharr[blippos+8] |= GLYPH_REDRAW;
55 glypharr[blippos+9] |= GLYPH_REDRAW;
56}
57
59{
60 int y;
61 GLYPH lastglyph = 0;
62 GLYPH thisglyph;
63
64 // wait until we are allowed to scroll
65 if(col->started == FALSE)
66 {
67 if(--col->countdown <= 0)
68 col->started = TRUE;
69
70 return;
71 }
72
73 // "seed" the glyph-run
74 lastglyph = col->state ? (GLYPH)0 : (GLYPH)(MAX_INTENSITY << 8);
75
76 //
77 // loop over the entire length of the column, looking for changes
78 // in intensity/darkness. This change signifies the start/end
79 // of a run of glyphs.
80 //
81 for(y = 0; y < col->length; y++)
82 {
83 thisglyph = col->glyph[y];
84
85 // bottom-most part of "run". Insert a new character (glyph)
86 // at the end to lengthen the run down the screen..gives the
87 // impression that the run is "falling" down the screen
88 if(GlyphIntensity(thisglyph) < GlyphIntensity(lastglyph) &&
89 GlyphIntensity(thisglyph) == 0)
90 {
91 col->glyph[y] = RandomGlyph(MAX_INTENSITY - 1);
92 y++;
93 }
94 // top-most part of "run". Delete a character off the top by
95 // darkening the glyph until it eventually disappears (turns black).
96 // this gives the effect that the run as dropped downwards
97 else if(GlyphIntensity(thisglyph) > GlyphIntensity(lastglyph))
98 {
99 col->glyph[y] = DarkenGlyph(thisglyph);
100
101 // if we've just darkened the last bit, skip on so
102 // the whole run doesn't go dark
103 if(GlyphIntensity(thisglyph) == MAX_INTENSITY - 1)
104 y++;
105 }
106
107 lastglyph = col->glyph[y];
108 }
109
110 // change state from blanks <-> runs when the current run as expired
111 if(--col->runlen <= 0)
112 {
113 if(col->state ^= 1)
114 col->runlen = crc_rand() % (3 * DENSITY/2) + DENSITY_MIN;
115 else
116 col->runlen = crc_rand() % (DENSITY_MAX+1-DENSITY) + (DENSITY_MIN*2);
117 }
118
119 //
120 // make a "blip" run down this column at double-speed
121 //
122
123 // mark current blip as redraw so it gets "erased"
124 if(col->blippos >= 0 && col->blippos < col->length)
125 RedrawBlip(col->glyph, col->blippos);
126
127 // advance down screen at double-speed
128 col->blippos += 2;
129
130 // if the blip gets to the end of a run, start it again (for a random
131 // length so that the blips never get synched together)
132 if(col->blippos >= col->bliplen)
133 {
134 col->bliplen = col->length + crc_rand() % 50;
135 col->blippos = 0;
136 }
137
138 // now redraw blip at new position
139 if(col->blippos >= 0 && col->blippos < col->length)
140 RedrawBlip(col->glyph, col->blippos);
141
142}
143
144//
145// randomly change a small collection glyphs in a column
146//
148{
149 int i, y;
150
151 for(i = 1, y = 0; i < 16; i++)
152 {
153 // find a run
154 while(GlyphIntensity(col->glyph[y]) < MAX_INTENSITY-1 && y < col->length)
155 y++;
156
157 if(y >= col->length)
158 break;
159
160 col->glyph[y] = (col->glyph[y] & 0xff00) | (crc_rand() % NUM_GLYPHS);
161 col->glyph[y] |= GLYPH_REDRAW;
162
163 y += crc_rand() % 10;
164 }
165}
166
167void DrawGlyph(MATRIX *matrix, HDC hdc, int xpos, int ypos, GLYPH glyph)
168{
169 int intensity = GlyphIntensity(glyph);
170 int glyphidx = glyph & 0xff;
171
172 BitBlt(hdc, xpos, ypos, GLYPH_WIDTH, GLYPH_HEIGHT, matrix->hdcBitmap,
173 glyphidx * GLYPH_WIDTH, intensity * GLYPH_HEIGHT, SRCCOPY);
174}
175
177{
178 int y;
179
180 // loop down the length of the column redrawing only what needs doing
181 for(y = 0; y < col->length; y++)
182 {
183 GLYPH glyph = col->glyph[y];
184
185 // does this glyph (character) need to be redrawn?
186 if(glyph & GLYPH_REDRAW)
187 {
188 if((y == col->blippos+0 || y == col->blippos+1 ||
189 y == col->blippos+8 || y == col->blippos+9) &&
190 GlyphIntensity(glyph) >= MAX_INTENSITY-1)
191 glyph |= MAX_INTENSITY << 8;
192
193 DrawGlyph(matrix, hdc, xpos, y * GLYPH_HEIGHT, glyph);
194
195 // clear redraw state
196 col->glyph[y] &= ~GLYPH_REDRAW;
197 }
198 }
199}
200
202{
203 int x;
204 HDC hdc = GetDC(hwnd);
205
206 for(x = 0; x < matrix->numcols; x++)
207 {
208 RandomMatrixColumn(&matrix->column[x]);
209 ScrollMatrixColumn(&matrix->column[x]);
211 }
212
213 if(matrix->message)
215
217}
218
219//
220// Allocate matrix structures
221//
223{
224 MATRIX *matrix;
225 HDC hdc;
226 int x, y;
227
228 int rows = height / GLYPH_HEIGHT + 1;
229 int cols = width / GLYPH_WIDTH + 1;
230
231 // allocate matrix!
232 if((matrix = malloc(sizeof(MATRIX) + sizeof(MATRIX_COLUMN) * cols)) == 0)
233 return 0;
234
235 matrix->numcols = cols;
236 matrix->numrows = rows;
237 matrix->width = width;
238 matrix->height = height;
239
240 for(x = 0; x < cols; x++)
241 {
242 matrix->column[x].length = rows;
243 matrix->column[x].started = FALSE;
244 matrix->column[x].countdown = crc_rand() % 100;
245 matrix->column[x].state = crc_rand() % 2;
246 matrix->column[x].runlen = crc_rand() % 20 + 3;
247
248 matrix->column[x].glyph = malloc(sizeof(GLYPH) * (rows+16));
249
250 for(y = 0; y < rows; y++)
251 matrix->column[x].glyph[y] = 0;//;
252 }
253
254 // Load bitmap!!
255 hdc = GetDC(NULL);
257 matrix->hdcBitmap = CreateCompatibleDC(hdc);
258 SelectObject(matrix->hdcBitmap, matrix->hbmBitmap);
260
261 // Create a message for this window...only if we are
262 // screen-saving (not if in preview mode)
263 if(GetParent(hwnd) == 0)
264 matrix->message = InitMatrixMessage(hwnd, matrix->numcols, matrix->numrows);
265 else
266 matrix->message = 0;
267
268 return matrix;
269}
270
271//
272// Free up matrix structures
273//
275{
276 int x;
277
278 // free the matrix columns
279 for(x = 0; x < matrix->numcols; x++)
280 free(matrix->column[x].glyph);
281
282 DeleteDC(matrix->hdcBitmap);
283 DeleteObject(matrix->hbmBitmap);
284
285 // now delete the matrix!
286 free(matrix);
287}
288
290{
292}
293
295{
297}
298
299//
300// Window procedure for one matrix (1 per screen)
301//
303{
304 static POINT ptLast;
305 static POINT ptCursor;
306 static BOOL fFirstTime = TRUE;
307
309
310 switch(msg)
311 {
312 // window creation
313 case WM_NCCREATE:
314
315 // create the matrix based on how big this window is
317
318 // failed to allocate? stop window creation!
319 if(matrix == 0)
320 return FALSE;
321
323
324 // start off an animation timer
325 SetTimer(hwnd, 0xdeadbeef, ((SPEED_MAX - g_nMatrixSpeed) + SPEED_MIN) * 10, 0);
326
327 return TRUE;
328
329 // window being destroyed, cleanup
330 case WM_NCDESTROY:
333 return 0;
334
335 // animation timer has gone off, redraw the matrix!
336 case WM_TIMER:
338 return 0;
339
340 // break out of screen-saver if any keyboard activity
341 case WM_KEYDOWN:
342 case WM_SYSKEYDOWN:
343 PostMessage(hwnd, WM_CLOSE, 0, 0);
344 return 0;
345
346 // break out of screen-saver if any mouse activity
347 case WM_LBUTTONDOWN:
348 case WM_LBUTTONUP:
349 case WM_RBUTTONDOWN:
350 case WM_RBUTTONUP:
351 case WM_MBUTTONDOWN:
352 case WM_MBUTTONUP:
353 case WM_MOUSEMOVE:
354
355 // If we've got a parent then we must be a preview
356 if(GetParent(hwnd) != 0)
357 return 0;
358
359 if(fFirstTime)
360 {
361 GetCursorPos(&ptLast);
362 fFirstTime = FALSE;
363 }
364
365 GetCursorPos(&ptCursor);
366
367 // if the mouse has moved more than 3 pixels then exit
368 if(abs(ptCursor.x - ptLast.x) >= 3 || abs(ptCursor.y - ptLast.y) >= 3)
369 PostMessage(hwnd, WM_CLOSE, 0, 0);
370
371 ptLast = ptCursor;
372
373 return 0;
374
375 // someone wants to close us...see if it's ok
376 case WM_CLOSE:
377
379 {
380 KillTimer(hwnd, 0xdeadbeef);
382 }
383
384 return 0;
385 }
386
388}
389
391{
392 DWORD dwStyle = hwndParent ? WS_CHILD : WS_POPUP;
393
394#ifdef _DEBUG
395 DWORD dwStyleEx = 0;
396#else
397 DWORD dwStyleEx = WS_EX_TOPMOST;
398#endif
399
400 if(hwndParent)
402
403 return CreateWindowEx( dwStyleEx,
404 APPNAME,
405 0,
406 WS_VISIBLE | dwStyle,
407 rect->left,
408 rect->top,
409 rect->right - rect->left,
410 rect->bottom - rect->top,
412 0,
414 0
415 );
416}
417
418//
419// Initialize class for matrix window
420//
422{
423 WNDCLASSEX wcx;
424
425 wcx.cbSize = sizeof(WNDCLASSEX);
426 wcx.style = 0;
428 wcx.cbClsExtra = 0;
429 wcx.cbWndExtra = sizeof(MATRIX *);
430 wcx.hInstance = GetModuleHandle(0);
431 wcx.hIcon = 0;
433 wcx.lpszMenuName = 0;
435 wcx.hIconSm = 0;
436
437 if(fPreview)
438 wcx.hCursor = LoadCursor(0, IDC_ARROW);
439 else
441
442 // initialize the crc register used for "random" number generation
444
445 RegisterClassEx(&wcx);
446}
#define APPNAME
Definition: 3dtext.c:40
#define msg(x)
Definition: auth_time.c:54
#define IDB_BITMAP1
Definition: resource.h:16
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
static HWND hwndParent
Definition: cryptui.c:300
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
static VOID NTAPI BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Delta)
Definition: common.c:49
#define abs(i)
Definition: fconv.c:206
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
pKey DeleteObject()
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLenum GLint GLuint mask
Definition: glext.h:6028
GLuint GLenum matrix
Definition: glext.h:9407
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
BOOL VerifyPassword(HWND hwnd)
Definition: password.c:12
#define MAX_INTENSITY
Definition: globals.h:15
int g_nMatrixSpeed
Definition: settings.c:18
#define DENSITY_MAX
Definition: globals.h:11
#define NUM_GLYPHS
Definition: globals.h:16
#define GLYPH_HEIGHT
Definition: globals.h:18
#define DENSITY
Definition: globals.h:10
#define DENSITY_MIN
Definition: globals.h:12
#define GLYPH_WIDTH
Definition: globals.h:17
#define SPEED_MAX
Definition: globals.h:20
#define SPEED_MIN
Definition: globals.h:21
int GlyphIntensity(GLYPH glyph)
Definition: matrix.c:30
void DecodeMatrix(HWND hwnd, MATRIX *matrix)
Definition: matrix.c:201
static WORD _crc_reg
Definition: matrix.c:17
void RedrawBlip(GLYPH *glypharr, int blippos)
Definition: matrix.c:50
HWND CreateScreenSaveWnd(HWND hwndParent, RECT *rect)
Definition: matrix.c:390
GLYPH RandomGlyph(int intensity)
Definition: matrix.c:45
void ScrollMatrixColumn(MATRIX_COLUMN *col)
Definition: matrix.c:58
void DoMatrixMessage(HDC hdc, MATRIX *matrix)
Definition: message.c:149
void RedrawMatrixColumn(MATRIX_COLUMN *col, MATRIX *matrix, HDC hdc, int xpos)
Definition: matrix.c:176
void RandomMatrixColumn(MATRIX_COLUMN *col)
Definition: matrix.c:147
void DrawGlyph(MATRIX *matrix, HDC hdc, int xpos, int ypos, GLYPH glyph)
Definition: matrix.c:167
void DestroyMatrix(MATRIX *matrix)
Definition: matrix.c:274
LRESULT WINAPI MatrixWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: matrix.c:302
MATRIX * GetMatrix(HWND hwnd)
Definition: matrix.c:289
int crc_rand()
Definition: matrix.c:18
MATRIX * CreateMatrix(HWND hwnd, int width, int height)
Definition: matrix.c:222
GLYPH DarkenGlyph(GLYPH glyph)
Definition: matrix.c:35
unsigned short GLYPH
Definition: matrix.h:18
#define GLYPH_REDRAW
Definition: matrix.h:20
void InitScreenSaveClass()
MATRIX_MESSAGE * InitMatrixMessage(HWND hwnd, int width, int height)
Definition: message.c:229
#define IDC_BLANKCURSOR
Definition: resource.h:6
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:92
@ SetMatrix
Definition: shader.c:1966
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define WS_CHILD
Definition: pedump.c:617
#define WS_POPUP
Definition: pedump.c:616
#define WS_VISIBLE
Definition: pedump.c:620
#define WS_EX_TOPMOST
Definition: pedump.c:647
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
#define DefWindowProc
Definition: ros2win.h:31
& rect
Definition: startmenu.cpp:1413
int countdown
Definition: matrix.h:30
int blippos
Definition: matrix.h:35
GLYPH * glyph
Definition: matrix.h:39
BOOL state
Definition: matrix.h:29
int runlen
Definition: matrix.h:33
int bliplen
Definition: matrix.h:36
int length
Definition: matrix.h:38
BOOL started
Definition: matrix.h:32
Definition: matrix.h:44
int cbClsExtra
Definition: winuser.h:3204
HINSTANCE hInstance
Definition: winuser.h:3206
HCURSOR hCursor
Definition: winuser.h:3208
LPCSTR lpszMenuName
Definition: winuser.h:3210
HICON hIconSm
Definition: winuser.h:3212
UINT style
Definition: winuser.h:3202
int cbWndExtra
Definition: winuser.h:3205
UINT cbSize
Definition: winuser.h:3201
WNDPROC lpfnWndProc
Definition: winuser.h:3203
LPCSTR lpszClassName
Definition: winuser.h:3211
HICON hIcon
Definition: winuser.h:3207
HBRUSH hbrBackground
Definition: winuser.h:3209
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
#define GetWindowLongPtr
Definition: treelist.c:73
#define SetWindowLongPtr
Definition: treelist.c:70
#define GWLP_USERDATA
Definition: treelist.c:63
#define GetModuleHandle
Definition: winbase.h:3762
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
HGDIOBJ WINAPI GetStockObject(_In_ int)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define SRCCOPY
Definition: wingdi.h:333
#define BLACK_BRUSH
Definition: wingdi.h:896
BOOL WINAPI DeleteDC(_In_ HDC)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define CreateWindowEx
Definition: winuser.h:5755
#define WM_CLOSE
Definition: winuser.h:1621
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define LoadBitmap
Definition: winuser.h:5811
#define IDC_ARROW
Definition: winuser.h:687
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2670
#define WM_RBUTTONUP
Definition: winuser.h:1780
#define WM_MOUSEMOVE
Definition: winuser.h:1775
#define WM_LBUTTONDOWN
Definition: winuser.h:1776
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define WM_NCCREATE
Definition: winuser.h:1683
#define WM_RBUTTONDOWN
Definition: winuser.h:1779
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define RegisterClassEx
Definition: winuser.h:5837
#define WM_TIMER
Definition: winuser.h:1742
#define LoadCursor
Definition: winuser.h:5812
WNDCLASSEXA WNDCLASSEX
Definition: winuser.h:5719
HDC WINAPI GetDC(_In_opt_ HWND)
#define WM_LBUTTONUP
Definition: winuser.h:1777
#define PostMessage
Definition: winuser.h:5832
HWND WINAPI GetParent(_In_ HWND)
#define WM_NCDESTROY
Definition: winuser.h:1684
#define WM_KEYDOWN
Definition: winuser.h:1715
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define WM_MBUTTONUP
Definition: winuser.h:1783
BOOL WINAPI DestroyWindow(_In_ HWND)
#define MAKEINTRESOURCE
Definition: winuser.h:591
#define WM_SYSKEYDOWN
Definition: winuser.h:1719
#define WM_MBUTTONDOWN
Definition: winuser.h:1782