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

📄 zgfx.cpp

📁 wince (windows mobile)绘制的很好实例,可以作为视频开发的参考
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <Windows.h>
#include "zgfx.h"
#include <gx.h>

#define BUFFER_XPITCH 2
#define BUFFER_YPITCH 2*m_screenbufwidth

//////////////////////////////////////////////////////////////////////////
GfxSubsys ZGfx::GfxGetSubSys()
{
	return m_usedsubsys;
}

//////////////////////////////////////////////////////////////////////////
GfxRetval ZGfx::GfxSuspend()
{
	if(m_usedsubsys==gfxGAPI && m_GXSuspend)
	{
		m_GXSuspend();
	}
	return GfxOK;
}

//////////////////////////////////////////////////////////////////////////
GfxRetval ZGfx::GfxResume()
{
	if(m_usedsubsys==gfxGAPI && m_GXResume)
	{
		m_GXResume();
	}
	return GfxOK;
}

//////////////////////////////////////////////////////////////////////////
bool ZGfx::GfxInitGAPI()
{
GXDisplayProperties prop;
int sw, sh;

	prop=m_GXGetDisplayProperties();
	m_cbpp=prop.cBPP;
	m_ypitch=prop.cbyPitch;
	m_xpitch=prop.cbxPitch;
	m_framebufheight=(unsigned short)prop.cyHeight;
	m_framebufwidth=(unsigned short)prop.cxWidth;

	if(!(prop.ffFormat&kfDirect565))
	{
		return false;
	}

	//now if it is a vga device, we have to check if GAPI's not messing it up
	sw=GetSystemMetrics(SM_CXSCREEN);
	sh=GetSystemMetrics(SM_CYSCREEN);
	if(sw!=prop.cxWidth || sh!=prop.cyHeight)
	{
		return false;
	}
	return true;
}

//////////////////////////////////////////////////////////////////////////
bool ZGfx::GfxInitDirectDraw()
{
LONG hr;

	hr=m_DirectDrawCreate(0, (IUnknown **)&m_pdd, 0);
	if(hr!=DD_OK)
	{
		return false;
	}

	hr=m_pdd->SetCooperativeLevel(m_hwnd, DDSCL_FULLSCREEN);
	if(hr!=DD_OK)
	{
		m_pdd->Release();
		m_pdd=0;
		return false;
	}

	memset((void *)&m_ddsd, 0, sizeof(m_ddsd));
	m_ddsd.dwSize = sizeof(m_ddsd);
	m_ddsd.dwFlags = DDSD_CAPS;
	m_ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;	//no back buffering, only use the visible display area

	//create surface (entire screen)
	hr=m_pdd->CreateSurface(&m_ddsd, &m_psurf, NULL);
	if(hr!=DD_OK )
	{
		m_pdd->Release();
		m_pdd=0;
		return false;
	}

	//get parameters with locking
	memset((void *)&m_ddsd, 0, sizeof(m_ddsd));
	m_ddsd.dwSize = sizeof(m_ddsd);
	hr=m_psurf->Lock(0, &m_ddsd, DDLOCK_WAITNOTBUSY, 0);
	if(hr!=DD_OK)
	{
		m_psurf->Release();
		m_psurf=0;
		m_pdd->Release();
		m_pdd=0;
		return false;
	}

	m_cbpp=m_ddsd.ddpfPixelFormat.dwRGBBitCount;
	m_xpitch=m_ddsd.lXPitch;
	m_ypitch=m_ddsd.lPitch;
	m_framebufwidth=(unsigned short)m_ddsd.dwWidth;
	m_framebufheight=(unsigned short)m_ddsd.dwHeight;

	//finally unlock surface
	m_psurf->Unlock(0);
	return true;
}

//////////////////////////////////////////////////////////////////////////
bool ZGfx::GfxLoadDirectDraw()
{
	m_hDD=LoadLibrary(L"ddraw.dll");
	if(m_hDD)
	{
		m_DirectDrawCreate=(DIRECTDRAWCREATE)GetProcAddress(m_hDD, L"DirectDrawCreate");
		return true;
	}
	else
	{
		return false;
	}
}

//////////////////////////////////////////////////////////////////////////
bool ZGfx::GfxInitRawFrameBufferAccess()
{
RawFrameBufferInfo rfbi;
HDC hdc;
bool retval;

	retval=false;
	hdc=GetDC(m_hwnd);		
	if(hdc)
	{
		if(ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, 0, sizeof(RawFrameBufferInfo), (char *) &rfbi))
		{
			if(rfbi.wFormat==FORMAT_565)
			{
				m_framebufwidth=rfbi.cxPixels;
				m_framebufheight=rfbi.cyPixels;
				m_xpitch=rfbi.cxStride;
				m_ypitch=rfbi.cyStride;
				m_cbpp=rfbi.wBPP;
				m_framebuf=rfbi.pFramePointer;
				retval=true;
			}
		}
		ReleaseDC(m_hwnd,hdc);
	}
	return retval;
}

//////////////////////////////////////////////////////////////////////////
bool ZGfx::GfxIsInitialized()
{
	return m_gfxinited;
}

//////////////////////////////////////////////////////////////////////////
bool ZGfx::GfxLoadGAPI()
{

	m_hGAPI=LoadLibrary(L"gx.dll");

	if(m_hGAPI)
	{
		m_GXOpenDisplay=(GXOPENDISPLAY)GetProcAddress(m_hGAPI, L"?GXOpenDisplay@@YAHPAUHWND__@@K@Z");
		m_GXCloseDisplay=(FARPROC)GetProcAddress(m_hGAPI, L"?GXCloseDisplay@@YAHXZ");
		m_GXGetDisplayProperties=(GXGETDISPLAYPROPERTIES)GetProcAddress(m_hGAPI, L"?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ");
		m_GXBeginDraw=(GXBEGINDRAW)GetProcAddress(m_hGAPI, L"?GXBeginDraw@@YAPAXXZ");
		m_GXEndDraw=(FARPROC)GetProcAddress(m_hGAPI, L"?GXEndDraw@@YAHXZ");
		m_GXOpenInput=(FARPROC)GetProcAddress(m_hGAPI, L"?GXOpenInput@@YAHXZ");
		m_GXCloseInput=(FARPROC)GetProcAddress(m_hGAPI, L"?GXCloseInput@@YAHXZ");
		m_GXGetDefaultKeys=(GXGETDEFAULTKEYS)GetProcAddress(m_hGAPI, L"?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z");
		m_GXSuspend=(FARPROC)GetProcAddress(m_hGAPI, L"?GXSuspend@@YAHXZ");
		m_GXResume=(FARPROC)GetProcAddress(m_hGAPI, L"?GXResume@@YAHXZ");
		return true;
	}
	else
	{
		return false;
	}
}

//////////////////////////////////////////////////////////////////////////
GfxRetval ZGfx::GfxCreateSurface(HWND hwnd, unsigned short width, unsigned short height, GfxSubsys *pUsedSubsys)
{
m_gfxinited=false;
OSVERSIONINFO osver;
bool dll_loaded=false;

	m_usedsubsys=gfxNone;
	//check windows version: must be pocket pc 2003 or windows mobile 5
	if(GetVersionEx(&osver)==false)
	{
		return GfxWindowsVersionError;
	}

	if(osver.dwMajorVersion<4)
	{
		return GfxWindowsVersionError;
	}
	
	m_hwnd=hwnd;

	if(!IsWindow(m_hwnd))
	{
		return GfxParameterError;
	}

	//scaling not supported
	if(width > GetSystemMetrics(SM_CXSCREEN) || height > GetSystemMetrics(SM_CYSCREEN))
	{
		return GfxParameterError;
	}

	//load GAPI lib - required for at least getting keycodes
	dll_loaded=GfxLoadGAPI();

	if(m_GXOpenInput) m_GXOpenInput();
	if(m_GXOpenDisplay) m_GXOpenDisplay(m_hwnd, GX_FULLSCREEN);	

	//decide which subsystem to use
	//first try raw framebuffer access
	if(GfxInitRawFrameBufferAccess())
	{
		m_usedsubsys=gfxRawFrameBuffer;
	}
	else
	{
		//otherwise if WM5, load DirectDraw
		if(osver.dwMajorVersion>4 && GfxLoadDirectDraw() && GfxInitDirectDraw())
		{
			m_usedsubsys=gfxDirectDraw;
		}
		else
		{
			//try gapi...
			if(GfxInitGAPI())
			{
				m_usedsubsys=gfxGAPI;
			}
			else
			//doh
			{
				return GfxUnsupportedDevice;
			}
		}
	}

	m_screenbufwidth=width;
	m_screenbufheight=height;

	if(m_cbpp!=16)
	{
		return GfxUnsupportedDevice;
	}

	m_framebufsize=m_framebufheight * m_framebufwidth * 2;
	m_screenbufsize=m_screenbufwidth * m_screenbufheight * 2;
	m_screenbuf=malloc(m_screenbufsize);

	if(!m_screenbuf)
	{
		return GfxMallocError;
	}

	//calculate centering offsets
	m_xcenter=m_ycenter=0;

	if(m_framebufwidth>m_screenbufwidth)
	{
		m_xcenter=(m_framebufwidth-m_screenbufwidth)/2;
	}
	if(m_framebufheight>m_screenbufheight)
	{
		m_ycenter=(m_framebufheight-m_screenbufheight)/2;
	}

	m_gfxinited=true;
	*pUsedSubsys=m_usedsubsys;
	return GfxOK;
}

//////////////////////////////////////////////////////////////////////////
GfxRetval ZGfx::GfxUninit()
{
	switch(m_usedsubsys)
	{
		case gfxGAPI:
		{
			if(m_GXEndDraw) m_GXEndDraw();
			break;
		}
		case gfxDirectDraw:
		{
			try
			{
				m_psurf->Release();
				m_psurf=0;
				m_pdd->Release();
				m_pdd=0;
			}
			catch (...)
			{
			}
			break;
		}
	}

	if(m_GXCloseInput) m_GXCloseInput();
	if(m_GXCloseDisplay) m_GXCloseDisplay();

	if(m_screenbuf)
	{
		free(m_screenbuf);
	}
	return GfxOK;
}

//////////////////////////////////////////////////////////////////////////
GfxRetval ZGfx::GfxUpdateScreen()
{
register WORD x,y,maxx,maxy;
register int xpitch,ypitch;
register BYTE *psrc, *pdest;

	//pre-blit pointer init
	switch(m_usedsubsys)
	{
		case gfxGAPI:
		{
			m_framebuf=m_GXBeginDraw();
			if(!m_framebuf)
			{
				return GfxBegindrawFailed;
			}
			break;
		}
		case gfxDirectDraw:
		{
			m_ddsd.dwSize = sizeof(m_ddsd);
			if(DD_OK!=m_psurf->Lock(0, &m_ddsd, DDLOCK_WAITNOTBUSY, 0))
			{
				return GfxSurfaceLockFailed;	
			}
			m_framebuf=m_ddsd.lpSurface;
			break;
		}
	}

	pdest=(BYTE *)m_framebuf;
	psrc=(BYTE *)m_screenbuf;

	xpitch=m_xpitch;
	ypitch=m_ypitch;

	pdest+=xpitch*m_xcenter;
	pdest+=ypitch*m_ycenter;

	//quick blit
	if(m_xpitch==2 && m_ypitch==2*m_screenbufwidth)
	{
		memcpy((void *)pdest, (void *)psrc, m_screenbufsize);
	}
	else
	//slow blit - pixel copy
	{
		maxx=m_screenbufwidth;
		maxy=m_screenbufheight;

		for(y=0;y<maxy;y++)
		{
			for(x=0;x<maxx;x++)
			{
				*(WORD *)pdest=*(WORD *)psrc;
				pdest+=xpitch;			
				psrc+=2;
			}
			pdest-=maxx*xpitch;
			pdest+=ypitch;
		}
	}

	//post-blit stuff
	switch(m_usedsubsys)
	{
		case gfxGAPI:
		{
			m_GXEndDraw();
			break;
		}
		case gfxDirectDraw:

⌨️ 快捷键说明

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