⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrixblitter.cpp

📁 矩阵编码和马尔可夫链的实现例程。实现类似黑客帝国数字屏保
💻 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 + -