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

📄 ddcompo.cpp

📁 赤壁之战(游戏原码)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////
//	DDCompo.cpp		:	v0043
//	Written by		:	Liu Gang
//	Compiler		:	Microsoft Visual C++ 4.0 & DirectX
//	Library			:	DDraw.Lib
//	Copyright (C)	:	1996 WayAhead Corporation 
//	v0020			:	Nov.12.1996
//	v0030			:	Dec.11.1996, upgrade to DirectDraw 2.0 or higher
//	v0031			:	Jan.22.1997, fix one reported bug, and change something in SetRange()
//	v0040			:	Feb.13.1997, changed some cursor functions, deleted surface m_lpSpriteBuffer
//	v0041			:	Mar.5.1997,	add member m_bShow and function Show()
//	v0042			:	Mar.22.1997, add some global functions for cursor
//						Fixed a bug when cursor is animating, add Erase() to CDDCursor
//	v0043			:	Apr.9.1997, changed the name of one of cursor's member m_bCreated to m_bCreatedC
/////////////
// implementation file
// DirectDraw components
// mouse cursor, framerate, etc
// 此文件与DDAPI结合比较紧密,使用了一些DDAPI的全局变量

#include "stdafx.h"
#include "Assert.h"	// ErrorMessage(), Assert()
#include "DDCompo.h"
#include "mmsystem.h"
#include "L_Allbmp.h"
//////////////////////////////

// globals
//////////////////////////////
// mouse cursor
class CDDCursor		*DDC_pCursor = NULL;	// current mouse cursor pointer
// MMX Cheater
extern MAIN_bMMX;
/////////

/////////
// frame rate
class CDDSurface	DDC_sFrameRate;
#ifdef	_DEBUG
BOOL                DDC_bShowFrameRate=TRUE;
#else
BOOL                DDC_bShowFrameRate=FALSE;
#endif
DWORD               DDC_dwFrameCount;
DWORD               DDC_dwFrameTime;
DWORD				DDC_dwFrames;

// display functions
#ifdef	_CURSOR_OLD_VERSION_
// sprite的显示范围
RECT	DDC_rcSpriteRange={0,0,SCREEN_WIDTH, SCREEN_HEIGHT};

// max size of each sprite
// sprite的矩形乘2或新旧位置的总矩形不能大于此值,用于优化显示
SIZE	DDC_szSpriteMax={320, 200};
#endif	// _CURSOR_OLD_VERSION_
////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////
// frame rate
/////////////////////////
// load frame rate file
// filename		:	bitmap file to display framerate
// return value	:	TRUE if succeeded
BOOL DDC_LoadFrameRate( LPCTSTR filename )
{
    DDC_dwFrameTime = timeGetTime();
	// no color key, in system memory
	if( !DDC_sFrameRate.LoadBitmap( filename, FALSE, FALSE ) )
		return FALSE;
	return TRUE;
}

// set if should show frame rate
// bShow	:	TRUE for show frame rate
void DDC_ShowFrameRate( BOOL bShow/* = TRUE */)
{
	DDC_bShowFrameRate = bShow;
	DDC_dwFrameCount = 0;
	DDC_dwFrameTime = timeGetTime();
	
	// update screen
	RECT rect;
	SetRect( &rect, 0, 0, 96, 16 );
	DDC_UpdateScreen( &rect );
}

// show display frame rate
void DDC_DisplayFrameRate( void )
{
    DWORD               time2;

	static DWORD        dwFramesLast;

	if( !DDC_bShowFrameRate )	return;

    DDC_dwFrameCount++;
    time2 = timeGetTime() - DDC_dwFrameTime;
    dwFramesLast = DDC_dwFrames;
    if( time2 > 1000 )
    {
        DDC_dwFrames = (DDC_dwFrameCount*1000)/time2;
        DDC_dwFrameTime = timeGetTime();
        DDC_dwFrameCount = 0;
    }

	if( DDC_dwFrames >999999 )	DDC_dwFrames = 999999;

	// drawing
	if( dwFramesLast == DDC_dwFrames )	return;

/*
	//--- MMX Cheater --- Liu Gang
	if( !MAIN_bMMX )
	{
		if( DDC_dwFrames < 5 ) DDC_dwFrames -= 1;
		else if( DDC_dwFrames < 10 ) DDC_dwFrames -= 2;
		else if( DDC_dwFrames < 20 ) DDC_dwFrames -= 4;
		else if( DDC_dwFrames < 30 ) DDC_dwFrames -= 6;
		else if( DDC_dwFrames < 40 ) DDC_dwFrames -= 8;
		if( DDC_dwFrames <= 0 )	DDC_dwFrames = 1;
	}
	//--- MMX Cheater ---
*/	
	DWORD dwFrames = DDC_dwFrames;
	// update to front buffer
	for ( int i=0; i< 6; i++ )
	{
		int num  = dwFrames%10;
		RECT rect;
		POINT ptDest;
		rect.top = 0;
		rect.bottom = 16;
		rect.left = 16*num;
		rect.right = rect.left + 16;
		ptDest.x = 16*5-16*i, ptDest.y = 0;
		DDC_sFrameRate.BltToFront( ptDest, &rect );
		dwFrames = dwFrames/10;
	}
}

// get frame rate
int DDC_GetFrameRate()
{
	return DDC_dwFrames;
}
////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////
// cursor
// constructor
CDDCursor::CDDCursor()
{
	m_bCreatedC = FALSE;
	m_bShow = TRUE;

#ifdef	_CURSOR_OLD_VERSION_
	m_lpSpriteBuffer = NULL;	// Sprite buffer
#endif	// _CURSOR_OLD_VERSION_

	m_lpMixBuffer = NULL;	// mix buffer

	m_szSize.cx = 0, m_szSize.cy = 0;
	GetCursorPos( &m_ptPos );

	m_rcRange.left = 0,
	m_rcRange.top = 0,
	m_rcRange.right = SCREEN_WIDTH,
	m_rcRange.bottom = SCREEN_HEIGHT;
	m_nState = DDC_CURSOR_STATE_NORMAL;
	m_nStateLast = DDC_CURSOR_STATE_NORMAL;
	m_nFrame = 0;
	m_nFrameLast = 0;
	m_nSpeed = 5;

	for( int i=0; i<DDC_CURSOR_STATE_MAX; i++ )
	{
		m_ptHotspot[i].x = 15,
		m_ptHotspot[i].y = 15;
	}

	for( int j=0; j<DDC_CURSOR_STATE_MAX; j++ )
		m_nFrameCount[j] = 1;
}

// destructor
CDDCursor::~CDDCursor()
{
	Release();
}

// load cursor
// create cursor 
// filename		:	cursor bitmap filename 
// nCol			:	cursor state, 横向排列在位图中,大小一样, cannot be zero
// nRow			:	cursor frame, 纵向排列在位图中,动画鼠标的每一帧, cannot be zero
// return value	:	TRUE if succeeded
BOOL CDDCursor::Load( LPCTSTR filename, int nCol/*=1*/, int pnRow[]/*=NULL*/, POINT pptHotspot[]/*=NULL*/ )
{
	// load bitmap from file
	// has color key, auto
	if( GetSurface() )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+7, "cannot load cursor twice!" );
		return FALSE;
	}
	// has color key, in system memory
	if( !LoadBitmap( filename, TRUE, FALSE ) )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+0, "Cannot open cursor bitmap file! ", filename );
		return FALSE;
	}
	
// set members
	// set size of cursor
	m_szSize = GetSize();

	// set frame counters, rows per column
	int nRowMax=1;
	if( pnRow )
	{
		for( int i=0; i<nCol; i++ )
		{
			m_nFrameCount[i] = pnRow[i];
			if( nRowMax < m_nFrameCount[i] )
				nRowMax = m_nFrameCount[i];
		}
	}

	// set hotspots of cursor in each state
	if( pptHotspot )
	{
		for( int i=0; i<nCol; i++ )
		{
			m_ptHotspot[i] = pptHotspot[i];
		}
	}

	if( nCol == 0 )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+1, "Column cannot be zero!" );
		return FALSE;
	}
	if( nRowMax == 0 )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+2, "Any row cannot be zero!" );
		return FALSE;
	}
	m_szSize.cy /= nCol;
	m_szSize.cx /= nRowMax;

	// create mix buffer
	BOOL retrn;
	if( m_lpMixBuffer )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+4, "cannot load cursor mix buffer twice!" );
		return FALSE;
	}
	m_lpMixBuffer = new CDDSurface;
	// no color key, in system memory
	retrn = m_lpMixBuffer->Create( m_szSize.cx*2, m_szSize.cy*2, FALSE, FALSE );
	if( !retrn )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+3, "Cannot create mix buffer for cursor!" );
		return FALSE;
	}

#ifdef	_CURSOR_OLD_VERSION_
	// create sprite buffer
	if( m_lpSpriteBuffer )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+5, "Cannot create cursor sprite buffer twice!" );
		return FALSE;
	}
	m_lpSpriteBuffer = new CDDSurface;
	// no color key, in system memory
	retrn = m_lpSpriteBuffer->Create( DDC_szSpriteMax.cx, DDC_szSpriteMax.cy, FALSE, FALSE );
	if( !retrn )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+6, "Cannot create sprite buffer for cursor!" );
		return FALSE;
	}
#endif	// _CURSOR_OLD_VERSION_

	m_bCreatedC = TRUE;
	return TRUE;
}

// load cursor
// create cursor 
// filename		:	cursor bitmap compact file
// nIndex		:	index number in compact file
// nCol			:	cursor state, 横向排列在位图中,大小一样, cannot be zero
// nRow			:	cursor frame, 纵向排列在位图中,动画鼠标的每一帧, cannot be zero
// return value	:	TRUE if succeeded
BOOL CDDCursor::LoadEx( LPSTR filename, LPSTR fileIndex, int nIndex, int nCol/*=1*/, int pnRow[]/*=NULL*/, POINT pptHotspot[]/*=NULL*/ )
{
	// load bitmap from file
	// has color key, auto
	if( GetSurface() )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+7, "cannot load cursor twice!" );
		return FALSE;
	}

	class CPicture_imageall picture;

	picture.image_open_compress(filename);
	picture.image_open_index(fileIndex);
	picture.LoadBitmap( this, nIndex );
	picture.image_close_index();
	picture.image_close_compress();

	SetColorKeyRGB( RGB(0,0,0) );

// set members
	// set size of cursor
	m_szSize = GetSize();

	// set frame counters, rows per column
	int nRowMax=1;
	if( pnRow )
	{
		for( int i=0; i<nCol; i++ )
		{
			m_nFrameCount[i] = pnRow[i];
			if( nRowMax < m_nFrameCount[i] )
				nRowMax = m_nFrameCount[i];
		}
	}

	// set hotspots of cursor in each state
	if( pptHotspot )
	{
		for( int i=0; i<nCol; i++ )
		{
			m_ptHotspot[i] = pptHotspot[i];
		}
	}

	if( nCol == 0 )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+1, "Column cannot be zero!" );
		return FALSE;
	}
	if( nRowMax == 0 )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+2, "Any row cannot be zero!" );
		return FALSE;
	}
	m_szSize.cy /= nCol;
	m_szSize.cx /= nRowMax;

	// create mix buffer
	BOOL retrn;
	if( m_lpMixBuffer )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+4, "cannot load cursor mix buffer twice!" );
		return FALSE;
	}
	m_lpMixBuffer = new CDDSurface;
	// no color key, in system memory
	retrn = m_lpMixBuffer->Create( m_szSize.cx*2, m_szSize.cy*2, FALSE, FALSE );
	if( !retrn )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+3, "Cannot create mix buffer for cursor!" );
		return FALSE;
	}

#ifdef	_CURSOR_OLD_VERSION_
	// create sprite buffer
	if( m_lpSpriteBuffer )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+5, "Cannot create cursor sprite buffer twice!" );
		return FALSE;
	}
	m_lpSpriteBuffer = new CDDSurface;
	// no color key, in system memory
	retrn = m_lpSpriteBuffer->Create( DDC_szSpriteMax.cx, DDC_szSpriteMax.cy, FALSE, FALSE );
	if( !retrn )
	{
		ErrorMessage( hwndGame, DDC_ERROR_ID+6, "Cannot create sprite buffer for cursor!" );
		return FALSE;
	}
#endif	// _CURSOR_OLD_VERSION_

	m_bCreatedC = TRUE;
	return TRUE;
}

// release cursor
void CDDCursor::Release()
{
	CDDSurface::Release();

#ifdef	_CURSOR_OLD_VERSION_
	if( m_lpSpriteBuffer )
	{
		m_lpSpriteBuffer->Release();
		delete m_lpSpriteBuffer;
		m_lpSpriteBuffer = NULL;
	}
#endif	// _CURSOR_OLD_VERSION_

	if( m_lpMixBuffer )
	{
		m_lpMixBuffer->Release();
		delete m_lpMixBuffer;
		m_lpMixBuffer = NULL;
	}
	m_bCreatedC = FALSE;
}

// set cursor moving range
// this may effects other cursor's range
// rcRange	:	new range for mouse moving in
// return value	:	old range for mouse moving in
// Warning	:	A bug report here:
//				Cannot erase old cursor if change range in run time
//				but this be fixed on Jan.22.1997
RECT CDDCursor::SetRange( CONST RECT *lprcRange )
{

	RECT rcRangeOld;
	rcRangeOld.left = m_rcRange.left,
	rcRangeOld.top = m_rcRange.top,
	rcRangeOld.right = m_rcRange.right,
	rcRangeOld.bottom = m_rcRange.bottom;

	// erase cursor in old position
	if( m_bCreatedC )
		DD_UpdateScreen( &GetRect() );

	m_rcRange.left = lprcRange->left,
	m_rcRange.top = lprcRange->top,
	m_rcRange.right = lprcRange->right,
	m_rcRange.bottom = lprcRange->bottom;

	// set cursor moving range
	ClipCursor( &m_rcRange );

	// redraw it right now
	if( m_bCreatedC )
		Draw( TRUE );
	
	return rcRangeOld;
}

// change cursor to next frame when display
void CDDCursor::Animate()
{

	Assert( m_bCreatedC );

	static int nTimer=0;
	nTimer ++;
	if( nTimer >= m_nSpeed )
	{
		nTimer = 0;
		m_nFrameLast = m_nFrame;
		m_nFrame = ( m_nFrame+1 )%m_nFrameCount[m_nState];
	}
	Draw( TRUE );
}

// set cursor state
// nState		:	new state
// return value	:	old state
int	CDDCursor::SetState( int nState )
{
	if( m_bCreatedC )
	{
		Erase();	// erase old
	}

	m_nStateLast = m_nState;
	m_nState = nState;
	// reset frame
	m_nFrameLast = m_nFrame;	m_nFrame = 0;
	if( m_bCreatedC )
	{
//		Draw( TRUE );	// draw new
	}
	return m_nStateLast;
}

// set cursor frame
// nFrame		:	new frame
// return value	:	old frame
int CDDCursor::SetFrame( int nFrame )
{
	m_nFrameLast = m_nFrame;
	m_nFrame = nFrame;
	if( m_bCreatedC )
		Draw( TRUE );
	return m_nFrameLast;
}

// set animate speed
// nSpeed		:	new speed
// return value	:	old speed
int CDDCursor::SetSpeed( int nSpeed )
{
	int nSpeedLast = m_nSpeed;
	m_nSpeed = nSpeed;
	return nSpeedLast;
}

// get cursor rectangle
RECT CDDCursor::GetRect()
{
	RECT rcDest;
	rcDest.left = m_ptPos.x - m_ptHotspot[m_nState].x;
	rcDest.top = m_ptPos.y - m_ptHotspot[m_nState].y;
	rcDest.right = rcDest.left + m_szSize.cx;
	rcDest.bottom = rcDest.top + m_szSize.cy;

⌨️ 快捷键说明

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