📄 matrixblitter.cpp
字号:
/*
Copyright (c) 2001
Author: Konstantin Boukreev
E-mail: konstantin@mail.primorye.ru
Created: 18.12.2001 11:31:31
Version: 1.0.0
*/
#include "stdafx.h"
#include "MatrixBlitter.h"
MatrixBlitter::stream::stream (unsigned pos, unsigned length, unsigned s, HSLModel hsll, HSLModel hsl2)
{
speed = s;
delay = 0;
x = pos;
y = 0;
hidden = false;
if (((double)rand() / RAND_MAX) > 0.75)
{
color = shift(hsll);
color2 = shift(hsl2);
}
else
{
color = hsll.rgb();
color2 = hsl2.rgb();
}
memset(&code, 0, length);
}
// static
unsigned MatrixBlitter::stream::shift (HSLModel hsl)
{
int lum = hsl.luminance();
lum = (int)((double)lum / 2 + ((double)lum / 2 ) * ((double)rand() / RAND_MAX));
hsl.luminance((BYTE)min(230, max(20, lum)));
return hsl.rgb();
}
MatrixBlitter::MatrixBlitter(fn_GetChar fn) :
m_hdc (0), m_bmp(0), m_unused(0),
m_brush(GetSysColorBrush(COLOR_BTNTEXT)), m_bcolor(GetSysColor(COLOR_BTNTEXT)),
m_font(0), m_font2(0),
m_hsl(RGB(0, 128, 0)), m_hsl2(RGB(128, 221, 128)),
m_cx(0), m_cy(0), m_height(0), m_width(0), m_char_cx(0), m_char_cy(0),
m_total(0), m_now(0),
m_speed2(3), m_speed1(0),
m_damping(0.75),
m_raw_mem(0),
m_fnGetChar(fn)
{
LOGFONT lf = {0};
// lstrcpy(lf.lfFaceName, _T("Comic Sans MS"));
// lstrcpy(lf.lfFaceName, _T("Terminal"));
// lstrcpy(lf.lfFaceName, _T("Courier New"));
// lstrcpy(lf.lfFaceName, _T("WP Japanese"));
lstrcpy(lf.lfFaceName, _T("Lucida Console"));
HDC hDC = ::GetDC(0);
lf.lfHeight = -MulDiv(7, GetDeviceCaps(hDC, LOGPIXELSY), 72);
::ReleaseDC(0, hDC);
lf.lfWeight = FW_NORMAL;
// lf.lfCharSet = SYMBOL_CHARSET; // for japanese
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfQuality = ANTIALIASED_QUALITY;
// lf.lfWeight = FW_BOLD;
m_font = CreateFontIndirect(&lf);
_ASSERTE(m_font);
lf.lfWeight = FW_BOLD;
m_font2 = CreateFontIndirect(&lf);
_ASSERTE(m_font2);
m_font_owner = true;
m_font2_owner = true;
}
MatrixBlitter::~MatrixBlitter()
{
if (m_font && m_font_owner) DeleteObject(m_font);
if (m_font2 && m_font2_owner) DeleteObject(m_font2);
if (m_brush) DeleteObject(m_brush);
Clear();
}
void MatrixBlitter::Init(HDC hdc, unsigned cx, unsigned cy, unsigned total)
{
Clear();
m_total = m_now = total;
m_cx = cx;
m_cy = cy;
m_hdc = CreateCompatibleDC(hdc);
m_bmp = CreateCompatibleBitmap(hdc, cx, cy);
m_unused = (HBITMAP)SelectObject(m_hdc, m_bmp);
_ASSERTE(m_hdc);
_ASSERTE(m_bmp);
HFONT h = (HFONT)::SelectObject(m_hdc, m_font);
TEXTMETRIC tm;
GetTextMetrics(m_hdc, &tm);
::SelectObject(m_hdc, h);
m_char_cy = tm.tmHeight;
m_char_cx = tm.tmAveCharWidth;
m_height = m_cy / m_char_cy;
m_width = m_cx / m_char_cx;
Generate();
}
void MatrixBlitter::Clear()
{
m_streams.clear();
if (m_raw_mem)
{
free (m_raw_mem);
m_raw_mem = 0;
}
if (m_hdc)
{
SelectObject(m_hdc, m_unused);
DeleteDC(m_hdc);
DeleteObject(m_bmp);
m_hdc = 0;
}
}
void MatrixBlitter::Blit(HDC hdc, int x, int y)
{
_ASSERTE(hdc);
_ASSERTE(m_hdc);
BOOL r = BitBlt(hdc, x, y, m_cx, m_cy, m_hdc, 0, 0, SRCCOPY);
_ASSERTE(r); r;
}
void MatrixBlitter::Refresh()
{
streams_t::iterator i;
int x = 0;
for (i = m_streams.begin(); i != m_streams.end(); ++i)
if ((*i)->delay != -1) ++x;
if ((unsigned)x != m_now)
x = m_now - x;
for (i = m_streams.begin(); i != m_streams.end(); ++i)
{
stream * p = (*i);
_ASSERTE(p->debug_trap == 0xd00dad);
UpdateStream(p);
if (p->hidden)
{
// recreate
new(p) stream (rand() % m_width, m_height,
m_speed1 + rand() % (m_speed2 - m_speed1), m_hsl, m_hsl2);
if (x < 0)
{
p->delay = -1;
++x;
}
}
else if (x > 0 &&
p->delay == -1)
{
--x;
p->delay = 0;
}
}
}
void MatrixBlitter::Render()
{
int save_dc = SaveDC(m_hdc);
RECT rc = {0, 0, m_cx, m_cy};
FillRect(m_hdc, &rc, m_brush);
// SetBkMode(m_hdc, TRANSPARENT);
SetBkColor(m_hdc, m_bcolor);
streams_t::iterator i;
SelectObject(m_hdc, m_font2);
for (i = m_streams.begin(); i != m_streams.end(); ++i)
{
stream * p = (*i);
if (p->delay == -1)
continue;
int y = p->y * m_char_cy;
int x = p->x * m_char_cx;
char* s = p->code;
if (y > 0 && y < (int)m_cy && s[p->y])
{
SetTextColor(m_hdc, p->color2);
TextOut(m_hdc, x, y, &s[p->y], 1);
}
}
SelectObject(m_hdc, m_font);
for (i = m_streams.begin(); i != m_streams.end(); ++i)
{
stream * p = (*i);
if (p->delay == -1)
continue;
int y = p->y * m_char_cy;
int x = p->x * m_char_cx;
char* s = p->code;
SetTextColor(m_hdc, p->color);
for (unsigned n = p->y; n > 0; --n)
{
y -= m_char_cy;
if (y > 0 && y < (int)m_cy && s[n])
{
TextOut(m_hdc, x, y, &s[n], 1);
}
}
}
RestoreDC(m_hdc, save_dc);
}
void MatrixBlitter::Generate()
{
_ASSERTE(!m_raw_mem);
m_raw_mem = malloc (m_total * (sizeof(stream) + m_height));
if (!m_raw_mem) return;
BYTE * b = (BYTE *)m_raw_mem;
m_streams.reserve(m_total);
for (unsigned n = 0; n < m_total; ++n)
{
stream * p = new(b) stream (rand() % m_width, m_height,
m_speed1 + rand() % (m_speed2 - m_speed1), m_hsl, m_hsl2);
#ifdef _DEBUG
p->debug_trap = 0xd00dad;
#endif
m_streams.push_back(p);
b += sizeof(stream) + m_height;
if (m_total > m_now)
p->delay = -1;
}
}
void MatrixBlitter::UpdateStream(stream * p)
{
_ASSERTE(!p->hidden);
if (p->delay > 0)
{
if (p->y < m_height && (p->delay % 2))
// p->code[p->y] = m_fnGetChar(((BYTE*)p - (BYTE*)m_raw_mem) / (sizeof(stream) + m_height));
p->code[p->y] = m_fnGetChar(-1);
--p->delay;
return;
}
else if (p->delay < 0)
{
// ++p->delay;
return;
}
p->delay = p->speed;
if (p->y < m_height)
{
if ( p->y &&
// (((rand() / RAND_MAX) > 0.25) && ((rand() % m_height) < p->y))
(((double)rand() / RAND_MAX) > m_damping)
)
{
p->code[rand() % p->y] = 0;
}
p->code[p->y] = m_fnGetChar(((BYTE*)p - (BYTE*)m_raw_mem) / (sizeof(stream) + m_height));
++p->y;
p->code[p->y] = m_fnGetChar(-1);
}
else if (p->y - m_height == m_height)
{
p->hidden = true;
}
else
{
++p->y;
p->code[p->y - m_height] = 0;
}
}
void MatrixBlitter::SetBackColor(unsigned color)
{
m_bcolor = color;
if (m_brush) DeleteObject(m_brush);
m_brush = CreateSolidBrush(color);
_ASSERTE(m_brush);
}
void MatrixBlitter::SetFont (HFONT f)
{
if (m_font && m_font_owner)
DeleteObject(m_font);
m_font = f;
m_font_owner = false;
}
void MatrixBlitter::SetHeadFont (HFONT f)
{
if (m_font2 && m_font2_owner)
DeleteObject(m_font2);
m_font2 = f;
m_font2_owner = false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -