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

📄 creditsthread.cpp

📁 电驴的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "stdafx.h"
#include "emule.h"
#include "CreditsThread.h"
#include "OtherFunctions.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

// define mask color
#define MASK_RGB	(COLORREF)0xFFFFFF

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNAMIC(CCreditsThread, CGDIThread)

BEGIN_MESSAGE_MAP(CCreditsThread, CGDIThread)
	//{{AFX_MSG_MAP(CCreditsThread)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CCreditsThread::CCreditsThread(CWnd* pWnd, HDC hDC, CRect rectScreen)
    : CGDIThread(pWnd,hDC)
{
	m_rectScreen = rectScreen;
	m_rgnScreen.CreateRectRgnIndirect(m_rectScreen);
	m_nScrollPos = 0;
	m_pbmpOldBk = NULL;
	m_pbmpOldCredits = NULL;
	m_pbmpOldScreen = NULL;
	m_pbmpOldMask = NULL;
	m_nCreditsBmpWidth = 0;
	m_nCreditsBmpHeight = 0;
}

CCreditsThread::~CCreditsThread() 
{
}

BOOL CCreditsThread::InitInstance()
{
	InitThreadLocale();
	BOOL bResult = CGDIThread::InitInstance();

	// NOTE: Because this is a separate thread, we have to delete our GDI objects here (while
	// the handle maps are still available.)
	if(m_dcBk.m_hDC != NULL && m_pbmpOldBk != NULL)
	{
		m_dcBk.SelectObject(m_pbmpOldBk);
		m_pbmpOldBk = NULL;
		m_bmpBk.DeleteObject();
	}

	if(m_dcScreen.m_hDC != NULL && m_pbmpOldScreen != NULL)
	{
		m_dcScreen.SelectObject(m_pbmpOldScreen);
		m_pbmpOldScreen = NULL;
		m_bmpScreen.DeleteObject();
	}

	if(m_dcCredits.m_hDC != NULL && m_pbmpOldCredits != NULL)
	{
		m_dcCredits.SelectObject(m_pbmpOldCredits);
		m_pbmpOldCredits = NULL;
		m_bmpCredits.DeleteObject();
	}

	if(m_dcMask.m_hDC != NULL && m_pbmpOldMask != NULL)
	{
		m_dcMask.SelectObject(m_pbmpOldMask);
		m_pbmpOldMask = NULL;
		m_bmpMask.DeleteObject();
	}

	// clean up the fonts we created
	for(int n = 0; n < m_arFonts.GetSize(); n++)
	{
		m_arFonts.GetAt(n)->DeleteObject();
		delete m_arFonts.GetAt(n);
	}
	m_arFonts.RemoveAll();

	return bResult;
}

// wait for vertical retrace
// makes scrolling smoother, especially at fast speeds
// NT does not like this at all
void waitvrt(void)
{
	__asm {
			mov	dx,3dah
	VRT:
			in		al,dx
			test	al,8
			jnz		VRT
	NoVRT:
			in		al,dx
			test	al,8
			jz		NoVRT
	}
}

void CCreditsThread::SingleStep()
{
	// if this is our first time, initialize the credits
	if(m_dcCredits.m_hDC == NULL)
	{
		CreateCredits();
	}

	// track scroll position
	static int nScrollY = 0;

	// timer variables
	LARGE_INTEGER nFrequency;
	LARGE_INTEGER nStart;
	LARGE_INTEGER nEnd;
	int nTimeInMilliseconds;
	BOOL bTimerValid;

	nStart.QuadPart = 0;

	if(!QueryPerformanceFrequency(&nFrequency))
	{
		bTimerValid = FALSE;
	}
	else
	{
		bTimerValid = TRUE;

		// get start time
		QueryPerformanceCounter(&nStart);
	}

	CGDIThread::m_csGDILock.Lock();
	{
		PaintBk(&m_dcScreen);

		m_dcScreen.BitBlt(0, 0, m_nCreditsBmpWidth, m_nCreditsBmpHeight, &m_dcCredits, 0, nScrollY, SRCINVERT);
		m_dcScreen.BitBlt(0, 0, m_nCreditsBmpWidth, m_nCreditsBmpHeight, &m_dcMask, 0, nScrollY, SRCAND);
		m_dcScreen.BitBlt(0, 0, m_nCreditsBmpWidth, m_nCreditsBmpHeight, &m_dcCredits, 0, nScrollY, SRCINVERT);

		// wait for vertical retrace
		if(m_bWaitVRT) waitvrt();

		m_dc.BitBlt(m_rectScreen.left, m_rectScreen.top, m_rectScreen.Width(), m_rectScreen.Height(), &m_dcScreen, 0, 0, SRCCOPY);

		GdiFlush();
	}
	CGDIThread::m_csGDILock.Unlock();

	// continue scrolling
	nScrollY += m_nScrollInc;
	if(nScrollY >= m_nCreditsBmpHeight) nScrollY = 0;	// scrolling up
	if(nScrollY < 0) nScrollY = m_nCreditsBmpHeight;	// scrolling down

	// delay scrolling by the specified time
	if(bTimerValid)
	{
		QueryPerformanceCounter(&nEnd);
		nTimeInMilliseconds = (int)((nEnd.QuadPart - nStart.QuadPart) * 1000 / nFrequency.QuadPart);

		if(nTimeInMilliseconds < m_nDelay)
		{
			Sleep(m_nDelay - nTimeInMilliseconds);
		}
	}
	else
	{
		Sleep(m_nDelay);
	}
}

void CCreditsThread::PaintBk(CDC* pDC)
{
	//save background the first time
	if (m_dcBk.m_hDC == NULL)
	{
		m_dcBk.CreateCompatibleDC(&m_dc);
		m_bmpBk.CreateCompatibleBitmap(&m_dc, m_rectScreen.Width(), m_rectScreen.Height());
		m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);
		m_dcBk.BitBlt(0, 0, m_rectScreen.Width(), m_rectScreen.Height(), &m_dc, m_rectScreen.left, m_rectScreen.top, SRCCOPY);
	}

	pDC->BitBlt(0, 0, m_rectScreen.Width(), m_rectScreen.Height(), &m_dcBk, 0, 0, SRCCOPY);
}

void CCreditsThread::CreateCredits()
{
	InitFonts();
	InitColors();
	InitText();

	m_dc.SelectClipRgn(&m_rgnScreen);

	m_dcScreen.CreateCompatibleDC(&m_dc);
	m_bmpScreen.CreateCompatibleBitmap(&m_dc, m_rectScreen.Width(), m_rectScreen.Height());
	m_pbmpOldScreen = m_dcScreen.SelectObject(&m_bmpScreen);

	m_nCreditsBmpWidth = m_rectScreen.Width();
	m_nCreditsBmpHeight = CalcCreditsHeight();

	m_dcCredits.CreateCompatibleDC(&m_dc);
	m_bmpCredits.CreateCompatibleBitmap(&m_dc, m_nCreditsBmpWidth, m_nCreditsBmpHeight);
	m_pbmpOldCredits = m_dcCredits.SelectObject(&m_bmpCredits);

	m_dcCredits.FillSolidRect(0, 0, m_nCreditsBmpWidth, m_nCreditsBmpHeight, MASK_RGB);

	CFont* pOldFont;

	pOldFont  = m_dcCredits.SelectObject(m_arFonts.GetAt(0));

	m_dcCredits.SetBkMode(TRANSPARENT);

	int y = 0;

	int nFont;
	int nColor;

	int nLastFont = -1;
	int nLastColor = -1;

	int nTextHeight = m_dcCredits.GetTextExtent(_T("Wy")).cy;

	for(int n = 0; n < m_arCredits.GetSize(); n++)
	{
		CString sType = m_arCredits.GetAt(n).Left(1);

		if(sType == 'B')
		{
			// it's a bitmap

			CBitmap bmp;
			if(! bmp.LoadBitmap(m_arCredits.GetAt(n).Mid(2)))
			{
				CString str; 
				str.Format(_T("Could not find bitmap resource \"%s\". Be sure to assign the bitmap a QUOTED resource name"), m_arCredits.GetAt(n).Mid(2)); 
				AfxMessageBox(str); 
				return; 
			}

			BITMAP bmInfo;
			bmp.GetBitmap(&bmInfo);

			CDC dc;
			dc.CreateCompatibleDC(&m_dcCredits);
			CBitmap* pOldBmp = dc.SelectObject(&bmp);

			// draw the bitmap
			m_dcCredits.BitBlt((m_rectScreen.Width() - bmInfo.bmWidth) / 2, y, bmInfo.bmWidth, bmInfo.bmHeight, &dc, 0, 0, SRCCOPY);

			dc.SelectObject(pOldBmp);
			bmp.DeleteObject();

			y += bmInfo.bmHeight;
		}
		else if(sType == 'S')
		{
			// it's a vertical space

			y += _ttoi(m_arCredits.GetAt(n).Mid(2));
		}
		else
		{
			// it's a text string

			nFont = _ttoi(m_arCredits.GetAt(n).Left(2));
			nColor = _ttoi(m_arCredits.GetAt(n).Mid(3,2));

			if(nFont != nLastFont)
			{
				m_dcCredits.SelectObject(m_arFonts.GetAt(nFont));
				nTextHeight = m_arFontHeights.GetAt(nFont);
			}

			if(nColor != nLastColor)
			{
				m_dcCredits.SetTextColor(m_arColors.GetAt(nColor));
			}

			CRect rect(0, y, m_rectScreen.Width(), y + nTextHeight);

			m_dcCredits.DrawText(m_arCredits.GetAt(n).Mid(6), &rect, DT_CENTER);

			y += nTextHeight;
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -