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 + -
显示快捷键?