-//\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;
+}