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