gsengine.cpp

来自「网络泡泡被.net管理」· C++ 代码 · 共 2,159 行 · 第 1/5 页

CPP
2,159
字号
// GsEngine.cpp: implementation of the CGsEngine class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#define D3D_OVERLOADS
#include <pbt.h>
#include <mmsystem.h>
#include <math.h>
#include <stdio.h>
#include <tchar.h>


#include "GSLib_Internal.h"


#define TIME_SHARE_TEX_DISUSE 2000	//2秒
#define TIME_SHARE_ANI_DISUSE 3000	//2秒

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

//-----------------------------------------------------------------------------
// Name: EnumZBufferFormatsCallback()
// Desc: Simply returns the first matching enumerated z-buffer format
//-----------------------------------------------------------------------------
static HRESULT WINAPI EnumZBufferFormatsCallback( DDPIXELFORMAT* pddpf,
                                                  VOID* pContext )
{
    DDPIXELFORMAT* pddpfOut = (DDPIXELFORMAT*)pContext;

    if( pddpfOut->dwRGBBitCount == pddpf->dwRGBBitCount )
    {
        (*pddpfOut) = (*pddpf);
        return D3DENUMRET_CANCEL;
    }

    return D3DENUMRET_OK;
}


//-----------------------------------------------------------------------------
// Name: CreateDibBMP()
// Desc: Created an empty bitmap, used exclusively in CreateBMPFromWindow().
//       Note that this is an internal (not exported) function.
//-----------------------------------------------------------------------------
static HBITMAP 
CreateDibBMP(HDC hdc, int w, int h, unsigned short bpp)
{
    LPVOID                      lpBits;
    struct
    {
        BITMAPINFOHEADER        bi;
        DWORD                   ct[256];
    } dib;

    dib.bi.biSize = sizeof(BITMAPINFOHEADER);
    dib.bi.biWidth = w;
    dib.bi.biHeight = h;
    dib.bi.biBitCount = bpp;
    dib.bi.biPlanes = 1;
    dib.bi.biCompression = 0;
    dib.bi.biSizeImage = 0;
    dib.bi.biClrUsed = 0;

    if (bpp == 15)
    {
        dib.bi.biBitCount = 16;
    }
    else
        if (bpp == 16)
        {
            dib.bi.biCompression = BI_BITFIELDS;
            dib.ct[0] = 0xF800;
            dib.ct[1] = 0x07E0;
            dib.ct[2] = 0x001F;
        }

    return CreateDIBSection(hdc, (LPBITMAPINFO) & dib, DIB_RGB_COLORS, &lpBits,
                            NULL, 0);
}




//-----------------------------------------------------------------------------
// Name: CreateBMPFromWindow()
// Desc: Takes the hwnd of the content window, and returns a bitmap handle.
//       Note that this is an internal (not exported) function.
//-----------------------------------------------------------------------------
static HBITMAP 
CreateBMPFromWindow(HWND hwnd)
{
    RECT                        rc;
    int                         x;
    int                         y;
    int                         cx;
    int                         cy;
    HDC                         hdcScreen;
    HDC                         hdcMemory;
    HBITMAP                     hbmBitmap;

    // Create a bitmap of the window passed in
    GetWindowRect(hwnd, &rc);
    x = rc.left;
    y = rc.top;
    cx = rc.right - rc.left;
    cy = rc.bottom - rc.top;
    hdcScreen = GetDC(NULL);
    hdcMemory = CreateCompatibleDC(NULL);
    hbmBitmap = CreateDibBMP(hdcScreen, cx, cy, 16);

    // BLT the image from screen to bitmap
    SelectObject(hdcMemory, hbmBitmap);
    BitBlt(hdcMemory, 0, 0, cx, cy, hdcScreen, x, y, SRCCOPY);
    DeleteDC(hdcMemory);
    ReleaseDC(NULL, hdcScreen);

    return hbmBitmap;
}



CGsEngine::CGsEngine()
{
	SetRect(&m_rcScreenRect,0,0,0,0);	
	SetRect(&m_rcRenderRect,0,0,0,0);
	SetRect(&m_rcSourceRect,0,0,0,0);
	m_isActive				= FALSE;
	m_isReady				= FALSE;
	m_pDD					= NULL;
	m_pD3D					= NULL;
	m_hWnd					= NULL;
	m_fsWnd					= NULL;
	m_isDismiss				= true;
	m_ID					= -1;
	m_enableBackgroundActive= false;
//	if( g_pGsApp != NULL )
//	{
//		m_ID					= g_pGsApp->m_gses.size();
//		g_pGsApp->m_gses.insert(GSES::value_type(m_ID,this));
//	}
	m_isCanRenderGDI		= false;
	m_FsWindowBMP			= NULL;
	m_isUseZBuffer			= false;
	m_isFullscreen			= FALSE;		
	m_isStereo				= FALSE;	
	m_pd3dDevice			= NULL;			
	m_pddsFrontBuffer		= NULL;		
	m_pddsBackBuffer		= NULL;		
	m_pBackSurface			= NULL;
	m_pFrontSurface			= NULL;
	m_pBackSurfaceLeft		= NULL;
	m_pddsBackBufferLeft	= NULL;	
	m_pddsZBuffer			= NULL;	
	m_pZBufferSurface		= NULL;
	m_dwRenderWidth			= 0L;
	m_dwRenderHeight		= 0L;
	m_dwDeviceMemType		= NULL;
	m_dwRefreshRate			= 300;
	m_pDeviceInfo			= g_pGsApp->GetDxDeviceInfoPtr();

	m_ptr_video				= NULL;

	m_pDS					= NULL;
	m_pDSListener			= NULL;
	m_sound_volume			= DSBVOLUME_MAX;
	m_media_volume			= DSBVOLUME_MAX;

	m_ptr_source			= NULL;
	m_ptr_game				= NULL;

	m_dwStepTime			= 0;
	m_dwBaseTime			= 0;
	m_dwStopTime			= 0;
	m_dwEngineTime			= 0;
	m_dwLastUpdateTime		= 0;
	m_dwPassTime			= 0;
	m_dwPausedCount			= 0;

	m_hMainMenu				= NULL;
	
	idr_command_auto		= 0;
	idr_command_updatemode	= 0;
	idr_command_step		= 0;
	idr_popup_menu			= 0;
	idr_choose_mode			= 0;	
	idr_command_pause		= 0;
	idr_command_operate		= 0;

	m_isSingleStep			= false;
	m_Pos.x					= 0;
	m_Pos.y					= 0;
	m_mouse_state			= 0;
	m_RenderStyle			= RS_STRETCH;
	m_dwStepRate	= 100;
	m_isViewportUse			= false;
	m_isWantZBuffer			= FALSE;
	m_isViewportUse			= false;

//	m_bUseHWBlt				= false;

	m_dwLastUpdateSecondTime	= 0;
	m_dwLastUpdateMinuteTime	= 0;


	m_isPreClear	= false;
	memset(&m_ddsdCurrentMode, 0, sizeof(m_ddsdCurrentMode));

	{
		for( WORD i=0, ix=0; ix<1; ix++ )
		{
			for( WORD iy=0; iy<1; iy++ )
			{
				m_apPaintIndices[i++] = (ix+0) + (iy+1)*(1+1);
				m_apPaintIndices[i++] = (ix+1) + (iy+0)*(1+1);
				m_apPaintIndices[i++] = (ix+0) + (iy+0)*(1+1);
				m_apPaintIndices[i++] = (ix+0) + (iy+1)*(1+1);
				m_apPaintIndices[i++] = (ix+1) + (iy+1)*(1+1);
				m_apPaintIndices[i++] = (ix+1) + (iy+0)*(1+1);
			}
		}
	}


	{
		m_apRectIndices[0]	= 0;
		m_apRectIndices[1]	= 1;
		m_apRectIndices[2]	= 3;
		m_apRectIndices[3]	= 2;
		m_apRectIndices[4]	= 0;

	}

	{
		for( WORD ix=0; ix<2; ix++ )
		{
			for( WORD iy=0; iy<2; iy++ )
			{
				FLOAT tu = ix;
				FLOAT tv = iy;

				m_apPaintVertex[ix+iy*(1+1)] = D3DTLVERTEX( D3DVECTOR(0.0f,0.0f,0.5f),
                                                            0.5f,
															0xffffffff,
															0,
															tu, tv );
			}
		}
	}




}
CGsEngine::~CGsEngine()
{
	OnFinalCleanup();
	g_pGsApp->m_gses.erase(g_pGsApp->m_gses.find(m_ID));
	CleanupParticles();
	DestroyEngine();
	m_animation_cache.clear();
	m_texture_cache.clear();
}


HRESULT CGsEngine::InitEngine( HWND hWnd, int width, int height, BOOL bResize )
{
	if(NULL==hWnd)
		return DDERR_INVALIDPARAMS;
	if( m_ID==-1 )
	{
		if( g_pGsApp != NULL )
		{
			m_ID					= g_pGsApp->m_gses.size();
			g_pGsApp->m_gses.insert(GSES::value_type(m_ID,this));
		}
		else
			return GSERR_NOTINITIALIZED;
	}
	else
	{
		DestroyEngine();
	}
	m_pDeviceInfo			= g_pGsApp->GetDxDeviceInfoPtr();
	// now create all number
	m_hWnd	= hWnd;
	HRESULT hr = S_OK;
	hr	= _CreateDriver();
	if(FAILED(hr))
		return hr;
	hr	= _CreateDevice(width, height, bResize);
	if(FAILED(hr))
		return hr;

	if(m_isOperating && m_isFullscreen)
	{
		//SetMenu(m_hWnd, m_hMainMenu);
		SetFsWindow (m_hWnd);
	}
	else
	{
		SetFsWindow(NULL);
	}


	hr	= _CreateSoundSystem();

	hr	= OnCreate();
	if(FAILED(hr))
		return hr;
	hr	= OnInitDevice();
	m_isDismiss	= false;
	m_isActive	= TRUE;

	if(idr_popup_menu>0)
		m_popupMenu	= LoadMenu( 0, MAKEINTRESOURCE(idr_popup_menu) );
	m_hMainMenu	= g_pGsApp->m_hMainMenu;

	g_pGsApp->OnEngineConnected(this);

	PrepareForRender();
	BuildParticles();
	return hr;
}

HRESULT CGsEngine::_CreateSoundSystem()
{
	HRESULT hr;
    // Create IDirectSound using the primary sound device
    if( FAILED( hr = DirectSoundCreate8( NULL, &m_pDS, NULL ) ) )
        return hr;//DXTRACE_ERR( TEXT("DirectSoundCreate8"), hr );

    // Set DirectSound coop level 
    if( FAILED( hr = m_pDS->SetCooperativeLevel( m_hWnd, DSSCL_PRIORITY ) ) )
        return hr;//DXTRACE_ERR( TEXT("SetCooperativeLevel"), hr );

    LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;

    if( m_pDS == NULL )
        return CO_E_NOTINITIALIZED;

    // Get the primary buffer 
    DSBUFFERDESC dsbd;
    ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
    dsbd.dwSize        = sizeof(DSBUFFERDESC);
    dsbd.dwFlags       = DSBCAPS_PRIMARYBUFFER;
    dsbd.dwBufferBytes = 0;
    dsbd.lpwfxFormat   = NULL;
       
    if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) )
        return hr;//DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr );

    WAVEFORMATEX wfx;
    ZeroMemory( &wfx, sizeof(WAVEFORMATEX) ); 
    wfx.wFormatTag      = WAVE_FORMAT_PCM; 
    wfx.nChannels       = 2;//(WORD) dwPrimaryChannels; 
    wfx.nSamplesPerSec  = 22050;//dwPrimaryFreq; 
    wfx.wBitsPerSample  = 16;//(WORD) dwPrimaryBitRate; 
    wfx.nBlockAlign     = wfx.wBitsPerSample / 8 * wfx.nChannels;
    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

    if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) )
        return hr;//DXTRACE_ERR( TEXT("SetFormat"), hr );

    SAFE_RELEASE( pDSBPrimary );


    // Obtain primary buffer, asking it for 3D control
    ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
    dsbd.dwSize = sizeof(DSBUFFERDESC);
    dsbd.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
    if( FAILED( hr = m_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) )
        return hr;//DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr );

    if( FAILED( hr = pDSBPrimary->QueryInterface( IID_IDirectSound3DListener, 
                                                  (VOID**)&m_pDSListener ) ) )
    {
        SAFE_RELEASE( pDSBPrimary );
        return hr;//DXTRACE_ERR( TEXT("QueryInterface"), hr );
    }

    // Release the primary buffer, since it is not need anymore
    SAFE_RELEASE( pDSBPrimary );
	return S_OK;
}



BOOL CGsEngine::Resume()
{

	return true;
}
//-----------------------------------------------------------------------------
// Name: ResumeAllSurface()
// Desc: 
//-----------------------------------------------------------------------------
HRESULT CGsEngine::RestoreSource()
{
	HRESULT	hr = S_OK;
	BuildParticles();
/*	std::map<KEY, CGsTexture*>::iterator	it_tex	= m_texture_cache.begin();
	while(it_tex!=m_texture_cache.end())
	{
		if(it_tex->second)
			it_tex->second->SetStreamSource(it_tex->first.c_str());
		it_tex++;
	}
*/
	std::map<KEY, CGsTextureGroup*>::iterator	it_ani	= m_animation_cache.begin();
	while(it_ani!=m_animation_cache.end())
	{
		if(it_ani->second)
			it_ani->second->RestoreObjects();
		it_ani++;
	}
	
	std::map<KEY, CGsTexture*>::iterator	it_tex	= m_texture_cache.begin();
	while(it_tex!=m_texture_cache.end())
	{
		if(it_tex->second)
			it_tex->second->RestoreObjects();
		it_tex++;
	}

	if(m_ptr_game)
		return m_ptr_game->RestoreSource();
	
	return hr;
}

⌨️ 快捷键说明

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