📄 halsurf.cpp
字号:
// -----------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// Copyright (c) 1997-1998 Microsoft Corporation
//
//
// written by: ESG Solution Center Munich
//
// Module Name: halsurf.cpp
//
// abstract: surface creation and flips
//
// -----------------------------------------------------------------------------
#include "precomp.h"
#if DXPAK
HRESULT
UpdateFlipStatus(GPE *pGPE)
{
if (pGPE->FlipInProgress())
return DDERR_WASSTILLDRAWING;
if (pGPE->IsBusy())
return DDERR_WASSTILLDRAWING;
return DD_OK;
}
DWORD WINAPI
HalFlipToGDISurface( LPDDHAL_FLIPTOGDISURFACEDATA pd )
{
DEBUGENTER( HalFlipToGDISurface );
/*
typedef struct _DDHAL_FLIPTOGDISURFACEDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
DWORD dwToGDI; // TRUE if flipping to the GDI surface, FALSE if flipping away
DWORD dwReserved; // reserved for future use
HRESULT ddRVal; // return value
LPDDHAL_FLIPTOGDISURFACE FlipToGDISurface; // PRIVATE: ptr to callback
} DDHAL_FLIPTOGDISURFACEDATA;
*/
if (pd->dwToGDI)
{
CT69000 *pGPE=(CT69000 *)pd->lpDD->hInstance;
LONG lOffset = (LONG) pGPE->PrimarySurface()->OffsetInVideoMemory();
pGPE->FlipTo(lOffset);
}
// Implementation
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
DWORD WINAPI HalCreateSurface( LPDDHAL_CREATESURFACEDATA pd )
{
DEBUGENTER( HalCreateSurface );
/*
typedef struct _DDHAL_CREATESURFACEDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDSURFACEDESC lpDDSurfaceDesc;// description of surface being created
LPDDRAWI_DDRAWSURFACE_LCL FAR *lplpSList; // list of created surface objects
DWORD dwSCnt; // number of surfaces in SList
HRESULT ddRVal; // return value
LPDDHAL_CREATESURFACE CreateSurface; // PRIVATE: ptr to callback
} DDHAL_CREATESURFACEDATA;
*/
DEBUGMSG(CT69K_ZONE_DDRAW,(TEXT("--create %d surfaces,\r\n"), pd->dwSCnt));
LPDDRAWI_DDRAWSURFACE_LCL lpSurf;
LPDDRAWI_DDRAWSURFACE_GBL lpSurf_gbl;
CT69000 *pGPE=(CT69000 *)pd->lpDD->hInstance;
//
// check here for primary surface creation
// if size of primary doesn't match the current mode,
// remember old mode and switch or reject
//
//
// iterate through list of surfaces to create
//
for(DWORD i=0;i<pd->dwSCnt;i++ )
{
GPESurf *pSurf;
lpSurf = pd->lplpSList[i];
lpSurf_gbl = lpSurf->lpGbl;
if ((i==0) &&
(lpSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
(lpSurf->ddsCaps.dwCaps & DDSCAPS_OVERLAY)==0)
{
//
// 69k has not enough memory to allow for triple buffered
// flipping chains! User might try again with 2 surf.
//
if (pd->dwSCnt>=3)
{
pd->ddRVal = DDERR_OUTOFMEMORY;
return DDHAL_DRIVER_HANDLED;
}
// do not reallocate primary surface...
pSurf=pGPE->PrimarySurface();
} else
{
SCODE sc;
DWORD dwSType=GPE_REQUIRE_VIDEO_MEMORY;
if (lpSurf->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)
dwSType = GPE_REQUIRE_VIDEO_MEMORY;
if (lpSurf->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
dwSType = 0;
if (lpSurf->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
dwSType |= GPE_SPECIAL_SURFACE;
dwSType |= GPE_DDRAW_SURFACE;
sc = pGPE->AllocSurface( &pSurf,
lpSurf_gbl->wWidth,
lpSurf_gbl->wHeight,
pGPE->GetFormat(),
dwSType);
if (sc != S_OK)
{
// Implementation
pd->ddRVal = DDERR_OUTOFMEMORY;
return DDHAL_DRIVER_HANDLED;
}
if (!pSurf->InVideoMemory())
{
lpSurf->ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
}
else
{
lpSurf->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
}
}
lpSurf_gbl->fpVidMem = (ULONG)pSurf->Buffer();
lpSurf_gbl->lPitch = pSurf->Stride();
lpSurf_gbl->dwReserved1 =
lpSurf->dwReserved1 = (DWORD) pSurf;
}
// Implementation
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
//////////////////////////// DDHAL_DDEXEBUFCALLBACKS ////////////////////////////
DWORD WINAPI
HalCanCreateSurface( LPDDHAL_CANCREATESURFACEDATA pd )
{
DEBUGENTER( HalCanCreateSurface );
/*
typedef struct _DDHAL_CANCREATESURFACEDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDSURFACEDESC lpDDSurfaceDesc; // description of surface being created
DWORD bIsDifferentPixelFormat;
// pixel format differs from primary surface
HRESULT ddRVal; // return value
LPDDHAL_CANCREATESURFACE CanCreateSurface;
// PRIVATE: ptr to callback
} DDHAL_CANCREATESURFACEDATA;
*/
// Implementation
/*
* - Well, nothing if surf has color format match screen format.
* - For Overlay: we support RGB8/16 and YUV422, doesn't care about
* screen format.
* - In DDRAWI.H, lpDDSurfaceDesc is declared as SURFACEDESC2 ???
*/
DDPIXELFORMAT *pddpf = &pd->lpDDSurfaceDesc->ddpfPixelFormat;
DWORD caps = pd->lpDDSurfaceDesc->ddsCaps.dwCaps;
if (pd->bIsDifferentPixelFormat ||
(caps & DDSCAPS_OVERLAY))
{
if (caps & DDSCAPS_OVERLAY) {
if (pddpf->dwFlags & DDPF_FOURCC) {
switch (pddpf->dwFourCC) {
case FOURCC_YUYV422:
/* just in case App doesn't fill this */
pddpf->dwYUVBitCount=16;
goto CanCreate;
break;
default:
goto CannotCreate;
}
}
else if (pddpf->dwFlags & DDPF_RGB) {
switch (pddpf->dwRGBBitCount) {
case 16:
goto CanCreate;
default:
goto CannotCreate;
}
}
}
}
CanCreate:
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
CannotCreate:
pd->ddRVal = DDERR_INVALIDPIXELFORMAT;
return DDHAL_DRIVER_HANDLED;
}
DWORD WINAPI
HalLock( LPDDHAL_LOCKDATA pd )
{
LPDDRAWI_DDRAWSURFACE_GBL lpSurf_gbl;
ULONG ulOffset=0;
DEBUGENTER( HalLock );
/*
typedef struct _DDHAL_LOCKDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDRAWI_DDRAWSURFACE_LCL lpDDSurface; // surface struct
DWORD bHasRect; // rArea is valid
RECTL rArea; // area being locked
LPVOID lpSurfData; // pointer to screen memory (return value)
HRESULT ddRVal; // return value
LPDDHALSURFCB_LOCK Lock; // PRIVATE: ptr to callback
} DDHAL_LOCKDATA;
*/
// Implementation
CT69000 *pGPE=(CT69000 *)pd->lpDD->hInstance;
if (!(pd->lpDDSurface->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY))
{
pd->ddRVal = UpdateFlipStatus(pGPE);
if (pd->ddRVal==DDERR_WASSTILLDRAWING)
{
if (pd->dwFlags & DDLOCK_WAIT)
{
while (UpdateFlipStatus(pGPE)!=DD_OK)
;
}
else
{
return DDHAL_DRIVER_HANDLED;
}
}
}
//
// wait for overlay flips if overlay surface
//
if (pd->lpDDSurface->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
{
if (pGPE->OvlFlipBusy())
{
if (pd->dwFlags & DDLOCK_WAIT)
{
while (pGPE->OvlFlipBusy())
;
}
else
{
pd->ddRVal=DDERR_WASSTILLDRAWING;
return DDHAL_DRIVER_HANDLED;
}
}
}
lpSurf_gbl = pd->lpDDSurface->lpGbl;
if (pd->bHasRect)
{
ulOffset += pGPE->BytesPerPixel(pd->rArea.left);
ulOffset += lpSurf_gbl->lPitch*pd->rArea.top;
}
pd->lpSurfData = (LPVOID)(lpSurf_gbl->fpVidMem+ulOffset);
pd->lpDDSurface->dwReserved1 = lpSurf_gbl->dwReserved1;
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
DWORD WINAPI
HalUnlock( LPDDHAL_UNLOCKDATA pd )
{
DEBUGENTER( HalUnlock );
/*
typedef struct _DDHAL_UNLOCKDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDRAWI_DDRAWSURFACE_LCL lpDDSurface; // surface struct
HRESULT ddRVal; // return value
LPDDHALSURFCB_UNLOCK Unlock; // PRIVATE: ptr to callback
} DDHAL_UNLOCKDATA;
*/
// Implementation
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
//////////////////////////// DDHAL_DDSURFACECALLBACKS ////////////////////////////
DWORD WINAPI HalDestroySurface( LPDDHAL_DESTROYSURFACEDATA pd )
{
DEBUGENTER( HalDestroySurface );
/*
typedef struct _DDHAL_DESTROYSURFACEDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDRAWI_DDRAWSURFACE_LCL lpDDSurface; // surface struct
HRESULT ddRVal; // return value
LPDDHALSURFCB_DESTROYSURFACE DestroySurface;// PRIVATE: ptr to callback
BOOL fDestroyGlobal;
} DDHAL_DESTROYSURFACEDATA;
*/
// Implementation
LPDDRAWI_DIRECTDRAW_GBL pdrv;
LPDDRAWI_DDRAWSURFACE_LCL psurf;
LPDDRAWI_DDRAWSURFACE_GBL psurf_gbl;
pdrv = pd->lpDD;
psurf = pd->lpDDSurface;
psurf_gbl = psurf->lpGbl;
GPE *pGPE =(GPE *)pdrv->hInstance;
if (psurf_gbl->dwReserved1)
{
GPESurf *lpSurf=(GPESurf *)psurf_gbl->dwReserved1;
if (lpSurf != pGPE->PrimarySurface())
{
delete lpSurf;
}
psurf_gbl->dwReserved1=NULL;
}
pd->ddRVal = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
DWORD WINAPI HalSetSurfaceDesc(LPDDHAL_HALSETSURFACEDESCDATA pd)
{
DEBUGENTER( HalSetSurfaceDesc );
/*
typedef struct _DDHAL_HALSETSURFACEDESCDATA
{
DWORD dwSize; // Size of this structure
LPDDRAWI_DDRAWSURFACE_LCL lpDDSurface; // Surface
LPDDSURFACEDESC lpddsd; // Description of surface
HRESULT ddrval;
} DDHAL_HALSETSURFACEDESCDATA;
*/
// Implementation
pd->ddrval = DD_OK;
return DDHAL_DRIVER_HANDLED;
}
DWORD WINAPI
HalFlip( LPDDHAL_FLIPDATA pd )
{
DEBUGENTER( HalFlip );
/*
typedef struct _DDHAL_FLIPDATA
{
LPDDRAWI_DIRECTDRAW_GBL lpDD; // driver struct
LPDDRAWI_DDRAWSURFACE_LCL lpSurfCurr; // current surface
LPDDRAWI_DDRAWSURFACE_LCL lpSurfTarg; // target surface (to flip to)
DWORD dwFlags; // flags
HRESULT ddRVal; // return value
LPDDHALSURFCB_FLIP Flip; // PRIVATE: ptr to callback
} DDHAL_FLIPDATA;
*/
CT69000 *pGPE=(CT69000 *)pd->lpDD->hInstance;
if (UpdateFlipStatus(pGPE)==DDERR_WASSTILLDRAWING)
{
if (pd->dwFlags & DDFLIP_WAIT)
{
while (UpdateFlipStatus(pGPE)==DDERR_WASSTILLDRAWING)
;
}
else
{
DEBUGMSG(GPE_ZONE_FLIP,(TEXT("Graphics engine busy\r\n")));
pd->ddRVal = DDERR_WASSTILLDRAWING;
return DDHAL_DRIVER_HANDLED;
}
}
LPDDRAWI_DDRAWSURFACE_LCL lpSurfTarg=pd->lpSurfTarg;
CT69000Surf *pSurf=(CT69000Surf *)lpSurfTarg->lpGbl->dwReserved1;
if (lpSurfTarg->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
{
if (pd->dwFlags & DDFLIP_WAIT)
{
while (pGPE->OvlFlipBusy())
;
} else
{
if (pGPE->OvlFlipBusy())
{
DEBUGMSG(GPE_ZONE_FLIP,(TEXT("overlay flip busy\r\n")));
pd->ddRVal=DDERR_WASSTILLDRAWING;
return DDHAL_DRIVER_HANDLED;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -