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

📄 dx_viewport.cpp

📁 彩信浏览器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player is free software; you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation; either version 2.1 of the License, or// (at your option) any later version.//// Ambulant Player 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 Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA/*  * @$Id: dx_viewport.cpp,v 1.44 2007/02/15 12:25:22 jackjansen Exp $  */#define INITGUID#include <objbase.h>#include <ddrawex.h>#include <uuids.h>#include <windows.h>#include <mmsystem.h>#include "ambulant/gui/dx/dx_viewport.h"#pragma comment (lib,"winmm.lib")#pragma comment (lib,"ddraw.lib")#pragma comment (lib,"dxguid.lib")#include "ambulant/lib/logger.h"#include "ambulant/lib/colors.h"#include "ambulant/lib/gtypes.h"#include "ambulant/lib/win32/win32_error.h"#include "ambulant/gui/dx/dx_transition.h"#include <algorithm>#include <cassert>using namespace ambulant;#ifndef AM_DBG#define AM_DBG if(0)#endifusing lib::uint16;using lib::uint32;using lib::uchar;using ambulant::lib::win32::win_report_error;using ambulant::lib::win32::win_report_last_error;static struct error {	HRESULT hr;	char *name;} errorlist [] = {	{DDERR_ALREADYINITIALIZED, "DDERR_ALREADYINITIALIZED"},	{DDERR_CANNOTATTACHSURFACE,"DDERR_CANNOTATTACHSURFACE"},	{DDERR_CANNOTDETACHSURFACE,"DDERR_CANNOTDETACHSURFACE"},	{DDERR_CURRENTLYNOTAVAIL,"DDERR_CURRENTLYNOTAVAIL"},	{DDERR_EXCEPTION,"DDERR_EXCEPTION"},	{DDERR_GENERIC,"DDERR_GENERIC"},	{DDERR_HEIGHTALIGN,"DDERR_HEIGHTALIGN"},	{DDERR_INCOMPATIBLEPRIMARY, "DDERR_INCOMPATIBLEPRIMARY"},	{DDERR_INVALIDCAPS, "DDERR_INVALIDCAPS"},	{DDERR_INVALIDCLIPLIST, "DDERR_INVALIDCLIPLIST"},	{DDERR_INVALIDMODE, "DDERR_INVALIDMODE"},	{DDERR_INVALIDOBJECT, "DDERR_INVALIDOBJECT"},	{DDERR_INVALIDPARAMS, "DDERR_INVALIDPARAMS"},	{DDERR_INVALIDPIXELFORMAT, "DDERR_INVALIDPIXELFORMAT"},	{DDERR_INVALIDRECT, "DDERR_INVALIDRECT"},	{DDERR_LOCKEDSURFACES, "DDERR_LOCKEDSURFACES"},	{DDERR_NO3D, "DDERR_NO3D"},	{DDERR_NOALPHAHW, "DDERR_NOALPHAHW"},#ifdef DDERR_NOSTEREOHARDWARE	{DDERR_NOSTEREOHARDWARE, "DDERR_NOSTEREOHARDWARE"},#endif#ifdef DDERR_NOSURFACELEFT	{DDERR_NOSURFACELEFT, "DDERR_NOSURFACELEFT"},#endif	{DDERR_NOCLIPLIST, "DDERR_NOCLIPLIST"},	{DDERR_NOCOLORCONVHW, "DDERR_NOCOLORCONVHW"},	{DDERR_NOCOOPERATIVELEVELSET, "DDERR_NOCOOPERATIVELEVELSET"},	{DDERR_NOCOLORKEY, "DDERR_NOCOLORKEY"},	{DDERR_NOCOLORKEYHW, "DDERR_NOCOLORKEYHW"},	{DDERR_NODIRECTDRAWSUPPORT, "DDERR_NODIRECTDRAWSUPPORT"},	{DDERR_NOEXCLUSIVEMODE, "DDERR_NOEXCLUSIVEMODE"},	{DDERR_NOFLIPHW, "DDERR_NOFLIPHW"},	{DDERR_NOGDI, "DDERR_NOGDI"},	{DDERR_NOMIRRORHW, "DDERR_NOMIRRORHW"},	{DDERR_NOTFOUND, "DDERR_NOTFOUND"},	{DDERR_NOOVERLAYHW, "DDERR_NOOVERLAYHW"},#ifdef DDERR_OVERLAPPINGRECTS	{DDERR_OVERLAPPINGRECTS, "DDERR_OVERLAPPINGRECTS"},#endif	{DDERR_NORASTEROPHW, "DDERR_NORASTEROPHW"},	{DDERR_NOROTATIONHW, "DDERR_NOROTATIONHW"},	{DDERR_NOSTRETCHHW, "DDERR_NOSTRETCHHW"},	{DDERR_NOT4BITCOLOR, "DDERR_NOT4BITCOLOR"},	{DDERR_NOT4BITCOLORINDEX, "DDERR_NOT4BITCOLORINDEX"},	{DDERR_NOT8BITCOLOR, "DDERR_NOT8BITCOLOR"},	{DDERR_NOTEXTUREHW, "DDERR_NOTEXTUREHW"},	{DDERR_NOVSYNCHW, "DDERR_NOVSYNCHW"},	{DDERR_NOZBUFFERHW, "DDERR_NOZBUFFERHW"},	{DDERR_NOZOVERLAYHW, "DDERR_NOZOVERLAYHW"},	{DDERR_OUTOFCAPS, "DDERR_OUTOFCAPS"},	{DDERR_OUTOFMEMORY, "DDERR_OUTOFMEMORY"},	{DDERR_OUTOFVIDEOMEMORY, "DDERR_OUTOFVIDEOMEMORY"},	{DDERR_OVERLAYCANTCLIP, "DDERR_OVERLAYCANTCLIP"},	{DDERR_OVERLAYCOLORKEYONLYONEACTIVE, "DDERR_OVERLAYCOLORKEYONLYONEACTIVE"},	{DDERR_PALETTEBUSY, "DDERR_PALETTEBUSY"},	{DDERR_COLORKEYNOTSET, "DDERR_COLORKEYNOTSET"},	{DDERR_SURFACEALREADYATTACHED, "DDERR_SURFACEALREADYATTACHED"},	{DDERR_SURFACEALREADYDEPENDENT, "DDERR_SURFACEALREADYDEPENDENT"},	{DDERR_SURFACEBUSY, "DDERR_SURFACEBUSY"},	{DDERR_CANTLOCKSURFACE, "DDERR_CANTLOCKSURFACE"},	{DDERR_SURFACEISOBSCURED, "DDERR_SURFACEISOBSCURED"},	{DDERR_SURFACELOST, "DDERR_SURFACELOST"},	{DDERR_SURFACENOTATTACHED, "DDERR_SURFACENOTATTACHED"},	{DDERR_TOOBIGHEIGHT, "DDERR_TOOBIGHEIGHT"},	{DDERR_TOOBIGSIZE, "DDERR_TOOBIGSIZE"},	{DDERR_TOOBIGWIDTH, "DDERR_TOOBIGWIDTH"},	{DDERR_UNSUPPORTED, "DDERR_UNSUPPORTED"},	{DDERR_UNSUPPORTEDFORMAT, "DDERR_UNSUPPORTEDFORMAT"},	{DDERR_UNSUPPORTEDMASK, "DDERR_UNSUPPORTEDMASK"},#ifdef DDERR_INVALIDSTREAM	{DDERR_INVALIDSTREAM, "DDERR_INVALIDSTREAM"},#endif	{DDERR_VERTICALBLANKINPROGRESS, "DDERR_VERTICALBLANKINPROGRESS"},	{DDERR_WASSTILLDRAWING, "DDERR_WASSTILLDRAWING"},#ifdef DDERR_DDSCAPSCOMPLEXREQUIRED	{DDERR_DDSCAPSCOMPLEXREQUIRED, "DDERR_DDSCAPSCOMPLEXREQUIRED"},#endif	{DDERR_XALIGN, "DDERR_XALIGN"},	{DDERR_INVALIDDIRECTDRAWGUID, "DDERR_INVALIDDIRECTDRAWGUID"},	{DDERR_DIRECTDRAWALREADYCREATED, "DDERR_DIRECTDRAWALREADYCREATED"},	{DDERR_NODIRECTDRAWHW, "DDERR_NODIRECTDRAWHW"},	{DDERR_PRIMARYSURFACEALREADYEXISTS, "DDERR_PRIMARYSURFACEALREADYEXISTS"},	{DDERR_NOEMULATION, "DDERR_NOEMULATION"},	{DDERR_REGIONTOOSMALL, "DDERR_REGIONTOOSMALL"},	{DDERR_CLIPPERISUSINGHWND, "DDERR_CLIPPERISUSINGHWND"},	{DDERR_NOCLIPPERATTACHED, "DDERR_NOCLIPPERATTACHED"},	{DDERR_NOHWND, "DDERR_NOHWND"},	{DDERR_HWNDSUBCLASSED, "DDERR_HWNDSUBCLASSED"},	{DDERR_HWNDALREADYSET, "DDERR_HWNDALREADYSET"},	{DDERR_NOPALETTEATTACHED, "DDERR_NOPALETTEATTACHED"},	{DDERR_NOPALETTEHW, "DDERR_NOPALETTEHW"},	{DDERR_BLTFASTCANTCLIP, "DDERR_BLTFASTCANTCLIP"},	{DDERR_NOBLTHW, "DDERR_NOBLTHW"},	{DDERR_NODDROPSHW, "DDERR_NODDROPSHW"},	{DDERR_OVERLAYNOTVISIBLE, "DDERR_OVERLAYNOTVISIBLE"},	{DDERR_NOOVERLAYDEST, "DDERR_NOOVERLAYDEST"},	{DDERR_INVALIDPOSITION, "DDERR_INVALIDPOSITION"},	{DDERR_NOTAOVERLAYSURFACE, "DDERR_NOTAOVERLAYSURFACE"},	{DDERR_EXCLUSIVEMODEALREADYSET, "DDERR_EXCLUSIVEMODEALREADYSET"},	{DDERR_NOTFLIPPABLE, "DDERR_NOTFLIPPABLE"},	{DDERR_CANTDUPLICATE, "DDERR_CANTDUPLICATE"},	{DDERR_NOTLOCKED, "DDERR_NOTLOCKED"},	{DDERR_CANTCREATEDC, "DDERR_CANTCREATEDC"},	{DDERR_NODC, "DDERR_NODC"},	{DDERR_WRONGMODE, "DDERR_WRONGMODE"},	{DDERR_IMPLICITLYCREATED, "DDERR_IMPLICITLYCREATED"},	{DDERR_NOTPALETTIZED, "DDERR_NOTPALETTIZED"},	{DDERR_UNSUPPORTEDMODE, "DDERR_UNSUPPORTEDMODE"},	{DDERR_NOMIPMAPHW, "DDERR_NOMIPMAPHW"},	{DDERR_INVALIDSURFACETYPE, "DDERR_INVALIDSURFACETYPE"},	{DDERR_NOOPTIMIZEHW, "DDERR_NOOPTIMIZEHW"},	{DDERR_NOTLOADED, "DDERR_NOTLOADED"},	{DDERR_NOFOCUSWINDOW, "DDERR_NOFOCUSWINDOW"},#ifdef DDERR_NOTONMIPMAPSUBLEVEL	{DDERR_NOTONMIPMAPSUBLEVEL, "DDERR_NOTONMIPMAPSUBLEVEL"},#endif	{DDERR_DCALREADYCREATED, "DDERR_DCALREADYCREATED"},	{DDERR_NONONLOCALVIDMEM, "DDERR_NONONLOCALVIDMEM"},	{DDERR_CANTPAGELOCK, "DDERR_CANTPAGELOCK"},	{DDERR_CANTPAGEUNLOCK, "DDERR_CANTPAGEUNLOCK"},	{DDERR_NOTPAGELOCKED, "DDERR_NOTPAGELOCKED"},	{DDERR_MOREDATA, "DDERR_MOREDATA"},#ifdef DDERR_EXPIRED	{DDERR_EXPIRED, "DDERR_EXPIRED"},#endif#ifdef DDERR_TESTFINISHED	{DDERR_TESTFINISHED, "DDERR_TESTFINISHED"},#endif#ifdef DDERR_NEWMODE	{DDERR_NEWMODE, "DDERR_NEWMODE"},#endif#ifdef DDERR_D3DNOTINITIALIZED	{DDERR_D3DNOTINITIALIZED, "DDERR_D3DNOTINITIALIZED"},#endif	{DDERR_VIDEONOTACTIVE, "DDERR_VIDEONOTACTIVE"},#ifdef DDERR_NOMONITORINFORMATION	{DDERR_NOMONITORINFORMATION, "DDERR_NOMONITORINFORMATION"},#endif#ifdef DDERR_NODRIVERSUPPORT	{DDERR_NODRIVERSUPPORT, "DDERR_NODRIVERSUPPORT"},#endif	{DDERR_DEVICEDOESNTOWNSURFACE, "DDERR_DEVICEDOESNTOWNSURFACE"},	{DDERR_NOTINITIALIZED, "DDERR_NOTINITIALIZED"},};#define RELEASE(x) if(x) x->Release();x=NULL;static lib::logger* viewport_logger = NULL;static voidseterror(const char *funcname, HRESULT hr){	char* pszmsg;	FormatMessage( 		 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,		 NULL,		 hr,		 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language		 (LPTSTR) &pszmsg,		 0,		 NULL 		);	for(error *p = errorlist; p->name; p++)		if (p->hr == hr){			viewport_logger->error("%s failed, error = %s (0x%x), %s", funcname, p->name, hr, pszmsg);			LocalFree(pszmsg);			return;		}	viewport_logger->error( "%s failed, error = %x, %s", funcname, hr, pszmsg);	LocalFree(pszmsg);}// wrapper for Blt on primary surface to check for recoverable errors#define MAX_RETRIES 1static void primary_Blt(IDirectDrawSurface* primary_surface, LPRECT lpDestRect, 			LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFX){	HRESULT hr = DD_OK;	int retries = MAX_RETRIES;	while (retries--) {		hr = primary_surface->Blt(lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFX);		if (hr == DDERR_SURFACELOST && retries >= 0) {			viewport_logger->trace("primary_Blt recovering from DDERR_LOSTSURFACE retry=%d", MAX_RETRIES-retries); 			hr = primary_surface->Restore();			if (FAILED(hr)) {				seterror("primary_Blt/DirectDrawSurface::Restore()", hr);				return;			}		} else break;	}	if (FAILED(hr))		seterror("primary_Blt/DirectDrawSurface::Blt()", hr);}const lib::color_t CLR_DEFAULT = RGB(255, 255, 255);gui::dx::viewport::viewport(int width, int height, HWND hwnd) :	m_width(width), m_height(height),	m_direct_draw(NULL),	m_primary_surface(NULL),	m_surface(NULL),	m_fstr_surface(NULL),	m_fstransition(NULL),	m_hwnd(hwnd?hwnd:GetDesktopWindow()),	bits_size(24),	red_bits(8), green_bits(8), blue_bits(8),	lo_red_bit(16), lo_green_bit(8), lo_blue_bit(0),	palette_entries(0),	m_bgd(CLR_DEFAULT) {		viewport_logger = lib::logger::get_logger();		IDirectDrawFactory *pDDF = NULL;    HRESULT hr = CoCreateInstance(CLSID_DirectDrawFactory,                              NULL, CLSCTX_INPROC_SERVER,                              IID_IDirectDrawFactory,                              (void **)&pDDF);	if (FAILED(hr)){		seterror("CoCreateInstance(CLSID_DirectDrawFactory, ...)", hr);		return;	}		IDirectDraw  *pDD1=NULL;	hr = pDDF->CreateDirectDraw(NULL, m_hwnd, DDSCL_NORMAL , 0, NULL, &pDD1);	pDDF->Release();	if (FAILED(hr)){		seterror("CreateDirectDraw()", hr);		return;	}	hr = pDD1->QueryInterface(IID_IDirectDraw2, (void**)&m_direct_draw);	if (FAILED(hr)){		seterror("QueryInterface(IID_IDirectDraw2,...)", hr);		pDD1->Release();		return;	}	pDD1->Release();	DWORD flags = DDSCL_NORMAL;	hr = m_direct_draw->SetCooperativeLevel(m_hwnd, flags);	if (FAILED(hr)) {		seterror("SetCooperativeLevel()", hr);		return;	}		// create primary surface	DDSURFACEDESC sd;	memset(&sd, 0, sizeof(DDSURFACEDESC));	sd.dwSize = sizeof(DDSURFACEDESC);	sd.dwFlags = DDSD_CAPS;	sd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;	hr = m_direct_draw->CreateSurface(&sd, &m_primary_surface, NULL);	if (FAILED(hr)) {		seterror("DirectDraw::CreateSurface()", hr);		return;	}	get_pixel_format();		// Clip output to the provided window	if(m_hwnd) {		IDirectDrawClipper *clipper = NULL; 		hr = m_direct_draw->CreateClipper(0, &clipper, NULL);		if (FAILED(hr))			seterror("DirectDraw::CreateClipper()", hr);		clipper->SetHWnd(0, m_hwnd);		hr = m_primary_surface->SetClipper(clipper);		if (FAILED(hr))			seterror("DirectDrawSurface::SetClipper()", hr);		clipper->Release();	}		// create drawing surface	memset(&sd, 0, sizeof(DDSURFACEDESC));	sd.dwSize = sizeof(DDSURFACEDESC);	sd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;	sd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;	sd.dwWidth = m_width;	sd.dwHeight = m_height;	hr = m_direct_draw->CreateSurface(&sd, &m_surface, NULL);	if (FAILED(hr)){		seterror("DirectDraw::CreateSurface()", hr);		return;	}		m_ddbgd = convert(m_bgd);		// clear the back buffer	clear();		// create shared transition surface	IDirectDrawSurface* surf;	memset(&sd, 0, sizeof(DDSURFACEDESC));	sd.dwSize = sizeof(DDSURFACEDESC);	sd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;	sd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;	sd.dwWidth = m_width;	sd.dwHeight = m_height;	hr = m_direct_draw->CreateSurface(&sd, &surf, NULL);	if (FAILED(hr)){		seterror("DirectDraw::CreateSurface()", hr);		return;	}	m_surfaces.push_back(surf);	memset(&sd, 0, sizeof(DDSURFACEDESC));	sd.dwSize = sizeof(DDSURFACEDESC);	sd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;	sd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;	sd.dwWidth = m_width;	sd.dwHeight = m_height;	hr = m_direct_draw->CreateSurface(&sd, &m_fstr_surface, NULL);	if (FAILED(hr)){		seterror("DirectDraw::CreateSurface()", hr);		return;	}}gui::dx::viewport::~viewport() {	std::list<IDirectDrawSurface*>::iterator it;	for(it=m_surfaces.begin();it!=m_surfaces.end();it++)		(*it)->Release();	RELEASE(m_surface);	RELEASE(m_primary_surface);	RELEASE(m_direct_draw);	RELEASE(m_fstr_surface);	if(palette_entries != 0)		delete[] palette_entries;	RedrawWindow(m_hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);}// Sets the background color of this viewportvoid gui::dx::viewport::set_background(lib::color_t color) {	m_bgd = (color == CLR_INVALID)?CLR_DEFAULT:color;	m_ddbgd = convert(m_bgd);}// Creates a DD surface with the provided size.// The surface is cleared using the specified colorIDirectDrawSurface* gui::dx::viewport::create_surface(DWORD w, DWORD h) {	IDirectDrawSurface* surface = 0;	DDSURFACEDESC sd;	memset(&sd, 0, sizeof(DDSURFACEDESC));	sd.dwSize = sizeof(DDSURFACEDESC);	sd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;	sd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;	sd.dwWidth = w;	sd.dwHeight = h;	HRESULT hr = m_direct_draw->CreateSurface(&sd, &surface, NULL);	if (FAILED(hr)){		seterror("DirectDraw::CreateSurface()", hr);		return 0;	}		return surface;}IDirectDrawSurface* gui::dx::viewport::create_surface() {	IDirectDrawSurface* surf = 0;	if(m_surfaces.empty()) {		return create_surface(m_width, m_height);	}	std::list<IDirectDrawSurface*>::iterator it = m_surfaces.begin();	surf = *it;	m_surfaces.erase(it);	return surf;}void gui::dx::viewport::release_surface(IDirectDrawSurface* surf) {	m_surfaces.push_back(surf);}// Blt back buffer to primary surfacevoid gui::dx::viewport::redraw() {	if(!m_primary_surface || !m_surface)		return;	RECT src_rc = {0, 0, m_width, m_height};	RECT dst_rc = {0, 0, m_width, m_height};	lib::rect ourrect(lib::point(0,0), lib::size(m_width, m_height));	DWORD flags = DDBLT_WAIT;	if (m_fstransition) {		AM_DBG lib::logger::get_logger()->debug("viewport::redraw: Applying fullscreen transition");		// Create a temp surface, determine bg/fg surfaces and copy the background

⌨️ 快捷键说明

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