📄 creditsthread.cpp
字号:
//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 + -