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

📄 ddapi.cpp

📁 网页游戏赤壁
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//////////////////////////////
//	DDAPI.cpp		:	v0039
//	Written by		:	Liu Gang
//	Compiler		:	Microsoft Visual C++ 4.0 & DirectX
//	Library			:	DDraw.Lib
//	Copyright (C)	:	1996 WayAhead Corporation 
//	v0010			:	Aug.26.1996
//	v0011			:	Sep.26.1996
//	v0020			:	Nov.8.1996
//					Warning: the width of the surface cannot larger than 640 pixel
//							when this occurs, there will be only a general error code
//							and return failed.
//	v0021			:	Nov.27.1996
//	v0030			:	Dec.11.1996, upgrade DirectDraw from 1.0 to 2.0
//	v0031			:	Feb.10.1997, fixed a bug that cannot release surfaces entirly
//						add a parameter to DD_EraseFrontScreen(), DD_EraseBckScreen() and CDDSurface::Erase()
//						add CDDSurface::SetColorKeyRGB() and CDDSurface::SetColorKeyPAL(), changed color key method
//	v0032			:	Mar.7.1997, Add a member "m_bInVideo" to CDDSurface
//						To decrease the load time when surface lost
//	v0033			:	Mar.10.1997
//					Warning:	when using Lock()/Unlock() to access surface,
//							please use ddsd.lPitch to stand for the width of 
//							the source surface. Mostly, the value in ddsd.dwWidth is equal to
//                          that in ddsd.lPitch. But if the surface is in video memory, and its
//							width is less than 640, and cannot devied by 4, they do not match before you 
//							draw ddsd.lpSurface to other surfaces.
//	v0034			:	April.1.1997, add function FadeOut() and FadeIn(), add surface and palette counter
//							add a member "m_bCreated" and a function IfCreated() to CDDSurface
//							add a member "m_strPalette" and a function Reload() to CDDPalette
//	v0035			:	Apr.9.1997, fixed a bug that generated by last version, did not initialize m_bCreated when 
//							constructing class instance, it took two whole days.
//	v0036			:	Apr.18.1997, add CS_DBLCLKS to window style
//	v0037			:	May.6.1997, add fadein and fadeout functions, and read palette from customed palette file
//	v0038			:	May.10.1997, edited fadein and fadeout functions, to make them easy to use.
//	v0039			:	May.12.1997, changed the global palette to object
//////////////////////////////


//////////////////////////////
// implementation file

// This file provide basic interfaces for DirectDraw with C++ 
// extension, so that someone can use more easily.
//////////////////////////////

#include "stdafx.h"

#include <stdio.h>
#include "DDAPI.h"
#include "DDutils.h"
#include "Assert.h"
#include "resource.h"

#define		MAX_SURFACE	256		// max surface is 256
#define		MAX_PALETTE	8		// max palette is 8

// Aug. 20. 1997
//#define _DD_SYSTEMMEMORY

#ifdef	_DEBUG
#define	_DD_DEBUG
#endif
//////////////////////////////
// globals
// major window object
HWND	hwndGame;
//////////////////////////////

//////////////////////////////
// locals
// abnormal structure: only one primary buffer
// not recommended to use global

// DirectDraw个体,唯一
LPDIRECTDRAW2           DD_lpDD=NULL;			// DirectDraw object

// 第一个面,显示面,全屏
LPDIRECTDRAWSURFACE2    DD_lpDDSFront=NULL;	// DirectDraw primary surface, front buffer

// 第二个面,用来保存背景,全屏
LPDIRECTDRAWSURFACE2    DD_lpDDSBack=NULL;		// DirectDraw secondary surface, back buffer

// 系统当前调色版
LPDIRECTDRAWPALETTE		DD_lpDDPal=NULL;		// current palette that primary surface is using

// global control, cannnot used outside
// 其它用户生成的面,封装内部操作
class CDDSurface		*DD_lppSurfaces[MAX_SURFACE];	// stores surfaces, max number is MAX_SURFACE
int						DD_nSurfaceCounter = 0;			// stores for the number of surfaces have been loaded
class CDDPalette		*DD_lppPalettes[MAX_PALETTE];	// stores palettes, max number is MAX_PALETTE
int						DD_nPaletteCounter = 0;			// stores for the number of palettes have been loaded

// 淡入淡出效果
int						nFadeLevel=0;				// current fading step
PALETTEENTRY			peFadeSave[256];			// save palette when fading
//added by tian yue.
PALETTEENTRY			pe[256];
BOOL					bFadeIn;					// TRUE for fading in
//////////////////////////////

// local functions
//////////////////////////////
// get blitter error when using BltFast() and Blt(), 
// not all the errors are here
// strHead	:	prefix string to be displayed
// ddrval	:	error number returned by BltFast() and Blt()
void DD_getBltError( char *strHead, int ddrval );

// get remained video memory, for debug version only
void DD_testVideoMemory();
//////////////////////////////

//////////////////////////////
// major window
//////////////////////////////
/*
 * initialize major window
 */
// hInstance	:	handle of application instance
// nCmdShow	:	show major window or not
// strName		:	window name
// return value:	handle of the window
HWND DD_InitWindow( HANDLE hInstance, int nCmdShow , LPCTSTR strName )
{
    WNDCLASS            wc;

    /*
     * set up and register window class
     */
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wc.lpfnWndProc = DD_WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = HINSTANCE(hInstance);
	// 用户要在其应用程序的资源编辑器里建立一个名为IDI_MAINGAME的图标
    wc.hIcon = LoadIcon( HINSTANCE(hInstance), MAKEINTRESOURCE(IDI_MAINGAME) );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground = HBRUSH(GetStockObject(BLACK_BRUSH));
    wc.lpszMenuName = strName;
    wc.lpszClassName = strName;
    RegisterClass( &wc );
    
    /*
     * create a window
     */
    hwndGame = CreateWindowEx(
        0,
        strName,
        strName,
        WS_POPUP,
        0,
        0,
        GetSystemMetrics(SM_CXSCREEN),
        GetSystemMetrics(SM_CYSCREEN),
        NULL,
        NULL,
        HINSTANCE(hInstance),
        NULL );

    if( !hwndGame )
    {
        DD_initFail(NULL, DD_ERROR_ID+90);
		return NULL;
    }
	SetCursor(NULL);	// hide cursor when begin application
    ShowWindow( hwndGame, nCmdShow );
    UpdateWindow( hwndGame );

	return hwndGame;
}	// DD_InitWindow()
//////////////////////////////

// graphic mode
//////////////////////////////
int gScreenWidth=0, gScreenHeight=0;
/*
 * Initialize graphic system
 */
// hwnd			:	handle of the major window
// nWidth, nHeight, nDepth:	the display mode of screen
// bInVideo		:	if 1, should load back buffer surface in video memory
//					if 0, should load back buffer surface in system memory
//					if -1, can load back buffer surface anywhere
// return value	:	TRUE if succeeded
BOOL DD_InitGraph( HWND hwnd, int nWidth/*=-1*/, int nHeight/*=-1*/, int nDepth/*=-1*/, int bInVideo/*=-1*/ )
{
    DDSURFACEDESC       ddsd;
    HRESULT             ddrval;

    /*
     * create the main DirectDraw object
     */
	LPDIRECTDRAW	lpDD = NULL;
    ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
    if( ddrval != DD_OK )
    {
        return DD_initFail(hwnd, DD_ERROR_ID+0);
    }
	// query direct draw object to object2
	ddrval = lpDD->QueryInterface(IID_IDirectDraw2, (LPVOID *)&DD_lpDD);
	if(ddrval != DD_OK)
	{
		return DD_initFail( hwnd, DD_ERROR_ID+6 );
	}
	// lpDD->Release();	// do not release, maybe useful

	gScreenWidth = GetSystemMetrics( SM_CXSCREEN );
	gScreenHeight = GetSystemMetrics( SM_CYSCREEN );
    // Get exclusive mode
#ifdef	_DD_DEBUG
    ddrval = DD_lpDD->SetCooperativeLevel( hwnd, DDSCL_NORMAL );
    if( ddrval != DD_OK )
    {
        return DD_initFail(hwnd, DD_ERROR_ID+1);
    }
#else
	ddrval = DD_lpDD->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT );
    if( ddrval != DD_OK )
    {
        return DD_initFail(hwnd, DD_ERROR_ID+3);
    }

    // Set the video mode to 640x480x256
	// SCREEN_WIDTH*SCREEN_HEIGHT*SCREEN_THICK
	if( nWidth == -1 ) nWidth = SCREEN_WIDTH;
	if( nHeight == -1 )	nHeight = SCREEN_HEIGHT;
	if( nDepth == -1 ) nDepth = SCREEN_THICK;
    ddrval = DD_lpDD->SetDisplayMode( nWidth, nHeight, nDepth, 0, 0 );
    if( ddrval != DD_OK )
    {
		if( nDepth > 8 )
		{
			DD_lpDD->SetCooperativeLevel( hwnd, DDSCL_NORMAL );
			DD_lpDD->Release();
			DD_lpDD = NULL;
			return FALSE;
		}
		else
			return DD_initFail(hwnd, DD_ERROR_ID+2);
    }
#endif

	// get remained video memory
#ifdef	_DEBUG
	if( bInVideo )
		DD_testVideoMemory();
#endif

    // Create the primary surface without back buffer
	LPDIRECTDRAWSURFACE	lpDDSFront = NULL;
    ddsd.dwSize = sizeof( ddsd );
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    ddrval = DD_lpDD->CreateSurface( &ddsd, &lpDDSFront, NULL );
    if( ddrval != DD_OK )
    {
        return DD_initFail(hwnd, DD_ERROR_ID+4);
    }
	// query direct draw surface to surface2
	ddrval = lpDDSFront->QueryInterface(IID_IDirectDrawSurface2, (LPVOID *)&DD_lpDDSFront);
	if(ddrval != DD_OK)
	{
		return DD_initFail( hwnd, DD_ERROR_ID+7 );
	}
	//lpDDSFront->Release();	// do not release, if so, 
								// when surface lost there are something wrong with that

	// get remained video memory
#ifdef	_DEBUG
	if( bInVideo )
		DD_testVideoMemory();
#endif

    // create secondary surface, back buffer
	LPDIRECTDRAWSURFACE lpDDSBack = NULL;
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
#ifdef	_DD_DEBUG
#else
#ifdef	_DD_SYSTEMMEMORY
	ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
#else
	if( bInVideo == 0 )
		ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
	else if( bInVideo == 1 )
		ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
#endif	// _DDSYSTEMMEMORY
#endif	// _DD_DEBUG
	// same size as full screen
    ddsd.dwWidth = SCREEN_WIDTH;
    ddsd.dwHeight = SCREEN_HEIGHT;
	ddrval = DD_lpDD->CreateSurface(&ddsd, &lpDDSBack, NULL);
    if( ddrval != DD_OK )
    {
		if( bInVideo )
		{
			// try in system memory again
			ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
			ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
			ddrval = DD_lpDD->CreateSurface(&ddsd, &lpDDSBack, NULL);
			if( ddrval != DD_OK )
				return DD_initFail(hwnd, DD_ERROR_ID+10);
		}
		else
			return DD_initFail(hwnd, DD_ERROR_ID+5);
	}
	// query direct draw surface to surface2
	ddrval = lpDDSBack->QueryInterface(IID_IDirectDrawSurface2, (LPVOID *)&DD_lpDDSBack);
	if(ddrval != DD_OK)
	{
		return DD_initFail( hwnd, DD_ERROR_ID+8 );
	}
	lpDDSBack->Release();	// must release, bug fix

// init other (user) surfaces
	for( int i=0 ; i< MAX_SURFACE; i++ )
		DD_lppSurfaces[i] = NULL;

// init other (user) palettes
	for( int j=0 ; j< MAX_PALETTE; j++ )
		DD_lppPalettes[j] = NULL;

//-------------
// init primary palette object
    PALETTEENTRY        ape[256];
    // build a 332 palette as the default.
    //
    for (i=0; i<256; i++)
    {
        ape[i].peRed   = (BYTE)(((i >> 5) & 0x07) * 255 / 7);
        ape[i].peGreen = (BYTE)(((i >> 2) & 0x07) * 255 / 7);
        ape[i].peBlue  = (BYTE)(((i >> 0) & 0x03) * 255 / 3);
        ape[i].peFlags = (BYTE)0;
    }
	DD_lpDD->CreatePalette(DDPCAPS_8BIT, ape, &DD_lpDDPal, NULL);
	if( DD_lpDDPal == NULL )
	{
		return DD_initFail(hwnd, DD_ERROR_ID+9);
	}
//-------------
	
	// clear screens
	DD_EraseFrontScreen();
	DD_EraseBackScreen();

	return TRUE;
} /* DD_InitGraph */


/*
 * quit graphic system, end DirectDraw section
 */
void DD_QuitGraph()
{
	HRESULT ddrval;

	if( DD_lpDD == NULL )
		return;

	// reset graph mode and cooperative level
    ddrval = DD_lpDD->SetDisplayMode( gScreenWidth, gScreenHeight, 8, 0, 0 );
	if( ddrval != DD_OK )
	{
	}

    ddrval = DD_lpDD->SetCooperativeLevel( hwndGame, DDSCL_NORMAL );
    if( ddrval != DD_OK )
    {
    }

	if( DD_lpDD != NULL )
	{
		// restore other surfaces
		for( int i=0 ; i< MAX_SURFACE; i++ )
		{
			if( DD_lppSurfaces[i] != NULL )
			{
				DD_lppSurfaces[i]->Release();
				DD_lppSurfaces[i] = NULL;
			}
		}
		Assert( DD_nSurfaceCounter == 0 );

//-------------
		// release primary palette
		if( DD_lpDDPal != NULL )
		{
			Assert( DD_lpDDPal != NULL );
			DD_lpDDPal->Release();
			DD_lpDDPal = NULL;
		}
//-------------

		// release palettes
		for( int j=0; j< MAX_PALETTE ; j++ )
		{
			if( DD_lppPalettes[j] != NULL )
			{
				DD_lppPalettes[j]->Release();
				DD_lppPalettes[j] = NULL;
			}
		}
		Assert( DD_nPaletteCounter == 0 );

		// release global surfaces
		if( DD_lpDDSFront )	
			DD_lpDDSFront->Release();	
		DD_lpDDSFront = NULL;
		if( DD_lpDDSBack )
			DD_lpDDSBack->Release();	
		DD_lpDDSBack = NULL;

		// release DirectDraw Object
		DD_lpDD->Release();
        DD_lpDD = NULL;
	}

/*
	LPDIRECTDRAW	lpDD = NULL;
    ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
    if( ddrval != DD_OK )
    {
		return;
    }
	// query direct draw object to object2
	ddrval = lpDD->QueryInterface(IID_IDirectDraw2, (LPVOID *)&DD_lpDD);
	if(ddrval != DD_OK)
	{
		return;
	}
	// lpDD->Release();	// do not release, maybe useful

	ddrval = DD_lpDD->SetCooperativeLevel( hwndGame, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT );
    if( ddrval != DD_OK )
    {
        return;
    }

    // Set the video mode to 640x480x256
	// SCREEN_WIDTH*SCREEN_HEIGHT*SCREEN_THICK
    ddrval = DD_lpDD->SetDisplayMode( gScreenWidth, gScreenHeight, 8, 0, 0 );
    if( ddrval != DD_OK )
    {
		return;
    }

    ddrval = DD_lpDD->SetCooperativeLevel( hwndGame, DDSCL_NORMAL );
    if( ddrval != DD_OK )
    {
		return;
    }
	if( DD_lpDD != NULL )
	{
		// release DirectDraw Object
		DD_lpDD->Release();
        DD_lpDD = NULL;
	}
*/
} /* DD_QuitGraph */


/*
 * This function is called if the initialization function fails
 */
// hwnd	:	handle of the parent window
// err		:	error ID
// return value:	Always FALSE
BOOL DD_initFail( HWND hwnd , int err )
{
	char buf[MAX_SURFACE];

    DD_QuitGraph();
    wsprintf(buf, "DirectDraw init FAILED (%d)", err);
    MessageBox( hwnd, buf, "ERROR", MB_OK );
    return FALSE;

} /* DD_initFail */

// get front buffer pointer
// return value	:	pointer of front buffer
inline LPDIRECTDRAWSURFACE2 DD_GetFrontBuffer( void )
{
	return DD_lpDDSFront;
}

// get back buffer pointer
// return value	:	pointer of back buffer
inline LPDIRECTDRAWSURFACE2 DD_GetBackBuffer( void )
{
	return DD_lpDDSBack;
}
//////////////////////////////

// screen
//////////////////////////////

⌨️ 快捷键说明

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