?? zgfx.cpp
字號:
#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 + -