ReactOS  0.4.13-dev-551-gf37fb1f
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
17 static WORD _crc_reg = 0;
18 int crc_rand()
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 
45 GLYPH RandomGlyph(int intensity)
46 {
47  return GLYPH_REDRAW | (intensity << 8) | (crc_rand() % NUM_GLYPHS);
48 }
49 
50 void 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 
167 void 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 
216  ReleaseDC(hwnd, hdc);
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);
259  ReleaseDC(NULL, hdc);
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:
332  PostQuitMessage(0);
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 
378  if(VerifyPassword(hwnd))
379  {
380  KillTimer(hwnd, 0xdeadbeef);
382  }
383 
384  return 0;
385  }
386 
387  return DefWindowProc(hwnd, msg, wParam, lParam);
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,
411  hwndParent,
412  0,
413  GetModuleHandle(0),
414  0
415  );
416 }
417 
418 //
419 // Initialize class for matrix window
420 //
421 void InitScreenSaveClass(BOOL fPreview)
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;
434  wcx.lpszClassName = APPNAME;
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 WM_MBUTTONUP
Definition: winuser.h:1759
HGDIOBJ WINAPI GetStockObject(_In_ int)
MATRIX_MESSAGE * InitMatrixMessage(HWND hwnd, int width, int height)
Definition: message.c:229
#define DENSITY_MAX
Definition: globals.h:11
#define abs(i)
Definition: fconv.c:206
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
UINT style
Definition: winuser.h:3155
#define MAKEINTRESOURCE
Definition: winuser.h:591
GLint GLint GLsizei width
Definition: gl.h:1546
LPCSTR lpszMenuName
Definition: winuser.h:3163
#define TRUE
Definition: types.h:120
#define RegisterClassEx
Definition: winuser.h:5703
int GlyphIntensity(GLYPH glyph)
Definition: matrix.c:30
long y
Definition: polytest.cpp:48
#define WM_LBUTTONDOWN
Definition: winuser.h:1752
HCURSOR hCursor
Definition: winuser.h:3161
WNDPROC lpfnWndProc
Definition: winuser.h:3156
long x
Definition: polytest.cpp:48
void DestroyMatrix(MATRIX *matrix)
Definition: matrix.c:274
GLYPH DarkenGlyph(GLYPH glyph)
Definition: matrix.c:35
HDC WINAPI GetDC(_In_opt_ HWND)
LPCSTR lpszClassName
Definition: winuser.h:3164
GLuint GLenum matrix
Definition: glext.h:9407
int bliplen
Definition: matrix.h:36
int runlen
Definition: matrix.h:33
#define free
Definition: debug_ros.c:5
#define DENSITY
Definition: globals.h:10
static HDC
Definition: imagelist.c:92
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
#define IDB_BITMAP1
Definition: resource.h:17
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
#define SPEED_MIN
Definition: globals.h:21
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
unsigned short GLYPH
Definition: matrix.h:18
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
UINT_PTR WPARAM
Definition: windef.h:207
#define WS_CHILD
Definition: pedump.c:617
HICON hIconSm
Definition: winuser.h:3165
GLYPH * glyph
Definition: matrix.h:39
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2635
#define MAX_INTENSITY
Definition: globals.h:15
#define WM_NCCREATE
Definition: winuser.h:1665
BOOL WINAPI DestroyWindow(_In_ HWND)
static VOID NTAPI BitBlt(IN ULONG Left, IN ULONG Top, IN ULONG Width, IN ULONG Height, IN PUCHAR Buffer, IN ULONG BitsPerPixel, IN ULONG Delta)
Definition: vga.c:410
#define SetWindowLongPtr
Definition: treelist.c:70
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
#define GLYPH_WIDTH
Definition: globals.h:17
#define GLYPH_REDRAW
Definition: matrix.h:20
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 state
Definition: matrix.h:29
GLenum GLint GLuint mask
Definition: glext.h:6028
BOOL started
Definition: matrix.h:32
HINSTANCE hInstance
Definition: winuser.h:3159
unsigned int BOOL
Definition: ntddk_ex.h:94
void DecodeMatrix(HWND hwnd, MATRIX *matrix)
Definition: matrix.c:201
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define SPEED_MAX
Definition: globals.h:20
#define CreateWindowEx
Definition: winuser.h:5621
#define GWLP_USERDATA
Definition: treelist.c:63
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
smooth NULL
Definition: ftsmooth.c:416
static HWND hwndParent
Definition: cryptui.c:300
void ScrollMatrixColumn(MATRIX_COLUMN *col)
Definition: matrix.c:58
#define WM_KEYDOWN
Definition: winuser.h:1691
LONG_PTR LPARAM
Definition: windef.h:208
UINT cbSize
Definition: winuser.h:3154
HBRUSH hbrBackground
Definition: winuser.h:3162
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define DefWindowProc
Definition: ros2win.h:31
#define WM_RBUTTONDOWN
Definition: winuser.h:1755
#define PostMessage
Definition: winuser.h:5698
#define BLACK_BRUSH
Definition: wingdi.h:895
#define LoadBitmap
Definition: winuser.h:5677
int countdown
Definition: matrix.h:30
Definition: matrix.h:43
void SetMatrix(HWND hwnd, MATRIX *matrix)
Definition: matrix.c:294
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
void RandomMatrixColumn(MATRIX_COLUMN *col)
Definition: matrix.c:147
#define WM_TIMER
Definition: winuser.h:1718
#define WM_CLOSE
Definition: winuser.h:1603
#define WM_NCDESTROY
Definition: winuser.h:1666
#define WINAPI
Definition: msvc.h:8
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define NUM_GLYPHS
Definition: globals.h:16
int cbWndExtra
Definition: winuser.h:3158
HWND CreateScreenSaveWnd(HWND hwndParent, RECT *rect)
Definition: matrix.c:390
#define WM_RBUTTONUP
Definition: winuser.h:1756
BOOL VerifyPassword(HWND hwnd)
Definition: password.c:12
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
HICON hIcon
Definition: winuser.h:3160
HDC hdc
Definition: main.c:9
int length
Definition: matrix.h:38
#define WS_EX_TOPMOST
Definition: pedump.c:647
#define LoadCursor
Definition: winuser.h:5678
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
MATRIX * CreateMatrix(HWND hwnd, int width, int height)
Definition: matrix.c:222
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
int crc_rand()
Definition: matrix.c:18
HWND WINAPI GetParent(_In_ HWND)
void InitScreenSaveClass(BOOL fPreview)
Definition: matrix.c:421
int cbClsExtra
Definition: winuser.h:3157
#define GetModuleHandle
Definition: winbase.h:3641
BOOL WINAPI DeleteDC(_In_ HDC)
#define WM_LBUTTONUP
Definition: winuser.h:1753
#define WM_MBUTTONDOWN
Definition: winuser.h:1758
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define WS_POPUP
Definition: pedump.c:616
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1751
#define APPNAME
Definition: 3dtext.c:40
void DrawGlyph(MATRIX *matrix, HDC hdc, int xpos, int ypos, GLYPH glyph)
Definition: matrix.c:167
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
int g_nMatrixSpeed
Definition: settings.c:18
LRESULT WINAPI MatrixWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: matrix.c:302
void RedrawMatrixColumn(MATRIX_COLUMN *col, MATRIX *matrix, HDC hdc, int xpos)
Definition: matrix.c:176
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
_Out_opt_ int * cx
Definition: commctrl.h:570
void DoMatrixMessage(HDC hdc, MATRIX *matrix)
Definition: message.c:149
#define WM_SYSKEYDOWN
Definition: winuser.h:1695
int blippos
Definition: matrix.h:35
#define malloc
Definition: debug_ros.c:4
WNDCLASSEXA WNDCLASSEX
Definition: winuser.h:5585
#define GetWindowLongPtr
Definition: treelist.c:73
LONG_PTR LRESULT
Definition: windef.h:209
#define IDC_BLANKCURSOR
Definition: resource.h:6
#define DENSITY_MIN
Definition: globals.h:12
#define GLYPH_HEIGHT
Definition: globals.h:18
GLYPH RandomGlyph(int intensity)
Definition: matrix.c:45
#define WS_VISIBLE
Definition: pedump.c:620
MATRIX * GetMatrix(HWND hwnd)
Definition: matrix.c:289
LPARAM lParam
Definition: combotst.c:139
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define SRCCOPY
Definition: wingdi.h:332
void RedrawBlip(GLYPH *glypharr, int blippos)
Definition: matrix.c:50
static WORD _crc_reg
Definition: matrix.c:17