📄 main.c
字号:
/* Create attached mipmaps if required. */ if (more_mipmaps(&ddsd)) { LPDIRECTDRAWSURFACE7 mipmap; LPDIRECTDRAWSURFACE7 prev_mipmap; DDSURFACEDESC2 mipmap_surface_desc; prev_mipmap = *ppSurf; IDirectDrawSurface7_AddRef(prev_mipmap); mipmap_surface_desc = ddsd; mipmap_surface_desc.ddsCaps.dwCaps2 |= DDSCAPS2_MIPMAPSUBLEVEL; while (more_mipmaps(&mipmap_surface_desc)) { IDirectDrawSurfaceImpl *mipmap_impl; mipmap_level++; mipmap_surface_desc.u2.dwMipMapCount--; if (mipmap_surface_desc.dwWidth > 1) mipmap_surface_desc.dwWidth /= 2; if (mipmap_surface_desc.dwHeight > 1) mipmap_surface_desc.dwHeight /= 2; mipmap_surface_desc.u1.lPitch = DDRAW_width_bpp_to_pitch(mipmap_surface_desc.dwWidth, GET_BPP(ddsd)*8); hr = This->create_texture(This, &mipmap_surface_desc, &mipmap, pUnkOuter, mipmap_level); if (FAILED(hr)) { IDirectDrawSurface7_Release(prev_mipmap); IDirectDrawSurface7_Release(*ppSurf); return hr; } /* This is needed for delayed mipmap creation */ mipmap_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap); mipmap_impl->mip_main = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf); mipmap_impl->mipmap_level = mipmap_level; if (This->d3d_private) This->d3d_create_texture(This, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, mipmap), TRUE, ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, *ppSurf)); IDirectDrawSurface7_AddAttachedSurface(prev_mipmap, mipmap); IDirectDrawSurface7_Release(prev_mipmap); prev_mipmap = mipmap; } IDirectDrawSurface7_Release(prev_mipmap); } return DD_OK;}/* Creates a primary surface and any indicated backbuffers. */static HRESULTcreate_primary(IDirectDrawImpl* This, LPDDSURFACEDESC2 pDDSD, LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter){ DDSURFACEDESC2 ddsd; HRESULT hr; assert(pUnkOuter == NULL); if (This->primary_surface != NULL) return DDERR_PRIMARYSURFACEALREADYEXISTS; /* as documented (what about pitch?) */ if (pDDSD->dwFlags & (DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT)) return DDERR_INVALIDPARAMS; ddsd.dwSize = sizeof(ddsd); DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD); ddsd.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH | DDSD_PITCH | DDSD_PIXELFORMAT; ddsd.dwHeight = This->height; ddsd.dwWidth = This->width; ddsd.u1.lPitch = This->pitch; ddsd.u4.ddpfPixelFormat = This->pixelformat; ddsd.ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE | DDSCAPS_FRONTBUFFER; if ((ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) && ddsd.dwBackBufferCount > 0) ddsd.ddsCaps.dwCaps |= DDSCAPS_FLIP; hr = This->create_primary(This, &ddsd, ppSurf, pUnkOuter); if (FAILED(hr)) return hr; if (ddsd.dwFlags & DDSD_BACKBUFFERCOUNT) { IDirectDrawSurfaceImpl* primary; LPDIRECTDRAWSURFACE7 pPrev; DWORD i; ddsd.dwFlags &= ~DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps &= ~(DDSCAPS_VISIBLE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER | DDSCAPS_FRONTBUFFER); primary = ICOM_OBJECT(IDirectDrawSurfaceImpl,IDirectDrawSurface7, *ppSurf); pPrev = *ppSurf; IDirectDrawSurface7_AddRef(pPrev); for (i=0; i < ddsd.dwBackBufferCount; i++) { LPDIRECTDRAWSURFACE7 pBack; if (i == 0) ddsd.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER; else ddsd.ddsCaps.dwCaps &= ~DDSCAPS_BACKBUFFER; hr = This->create_backbuffer(This, &ddsd, &pBack, pUnkOuter, primary); if (FAILED(hr)) { IDirectDraw7_Release(pPrev); IDirectDraw7_Release(*ppSurf); return hr; } IDirectDrawSurface7_AddAttachedSurface(pPrev, pBack); IDirectDrawSurface7_Release(pPrev); pPrev = pBack; } IDirectDrawSurface7_Release(pPrev); } This->primary_surface = (IDirectDrawSurfaceImpl *)*ppSurf; return DD_OK;}static HRESULTcreate_offscreen(IDirectDrawImpl* This, LPDDSURFACEDESC2 pDDSD, LPDIRECTDRAWSURFACE7* ppSurf, LPUNKNOWN pUnkOuter){ DDSURFACEDESC2 ddsd; HRESULT hr; /* is this check right? (pixelformat can be copied from primary) */ if ((pDDSD->dwFlags&(DDSD_HEIGHT|DDSD_WIDTH)) != (DDSD_HEIGHT|DDSD_WIDTH)) return DDERR_INVALIDPARAMS; ddsd.dwSize = sizeof(ddsd); DD_STRUCT_COPY_BYSIZE((&ddsd),pDDSD); if (!(ddsd.dwFlags & DDSD_PIXELFORMAT)) { ddsd.u4.ddpfPixelFormat = This->pixelformat; } if (!(ddsd.dwFlags & DDSD_PITCH)) { ddsd.u1.lPitch = DDRAW_width_bpp_to_pitch(ddsd.dwWidth, GET_BPP(ddsd)*8); } ddsd.dwFlags |= DDSD_PITCH | DDSD_PIXELFORMAT; hr = This->create_offscreen(This, &ddsd, ppSurf, pUnkOuter); if (FAILED(hr)) return hr; return hr;}HRESULT WINAPIMain_DirectDraw_CreateSurface(LPDIRECTDRAW7 iface, LPDDSURFACEDESC2 pDDSD, LPDIRECTDRAWSURFACE7 *ppSurf, IUnknown *pUnkOuter){ HRESULT hr; ICOM_THIS(IDirectDrawImpl, iface); TRACE("(%p)->(%p,%p,%p)\n",This,pDDSD,ppSurf,pUnkOuter); if (TRACE_ON(ddraw)) { TRACE("Requesting surface desc :\n"); DDRAW_dump_surface_desc(pDDSD); } if (pUnkOuter != NULL) { FIXME("outer != NULL?\n"); return CLASS_E_NOAGGREGATION; /* unchecked */ } if (!(pDDSD->dwFlags & DDSD_CAPS)) { /* DVIDEO.DLL does forget the DDSD_CAPS flag ... *sigh* */ pDDSD->dwFlags |= DDSD_CAPS; } if (pDDSD->ddsCaps.dwCaps == 0) { /* This has been checked on real Windows */ pDDSD->ddsCaps.dwCaps = DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY; } if (pDDSD->ddsCaps.dwCaps & DDSCAPS_ALLOCONLOAD) { /* If the surface is of the 'alloconload' type, ignore the LPSURFACE field */ pDDSD->dwFlags &= ~DDSD_LPSURFACE; } if (ppSurf == NULL) { FIXME("You want to get back a surface? Don't give NULL ptrs!\n"); return E_POINTER; /* unchecked */ } if (pDDSD->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { /* create primary surface & backbuffers */ hr = create_primary(This, pDDSD, ppSurf, pUnkOuter); } else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_BACKBUFFER) { /* create backbuffer surface */ hr = This->create_backbuffer(This, pDDSD, ppSurf, pUnkOuter, NULL); } else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE) { /* create texture */ hr = create_texture(This, pDDSD, ppSurf, pUnkOuter); } else if ((pDDSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) || (pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) /* No difference in Wine right now */ { /* create offscreenplain surface */ hr = create_offscreen(This, pDDSD, ppSurf, pUnkOuter); } else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) { /* create z-buffer */ hr = This->create_zbuffer(This, pDDSD, ppSurf, pUnkOuter); } else { /* Otherwise, assume offscreenplain surface */ TRACE("App didn't request a valid surface type - assuming offscreenplain\n"); hr = create_offscreen(This, pDDSD, ppSurf, pUnkOuter); } if (FAILED(hr)) { FIXME("failed surface creation with code 0x%08lx\n",hr); return hr; } return DD_OK;}HRESULT WINAPIMain_DirectDraw_DuplicateSurface(LPDIRECTDRAW7 iface, LPDIRECTDRAWSURFACE7 src, LPDIRECTDRAWSURFACE7* dst){ ICOM_THIS(IDirectDrawImpl,iface); IDirectDrawSurfaceImpl *pSrc = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src); TRACE("(%p)->(%p,%p)\n",This,src,dst); return pSrc->duplicate_surface(pSrc, dst);}/* EnumDisplayModes */BOOL Main_DirectDraw_DDPIXELFORMAT_Match(const DDPIXELFORMAT *requested, const DDPIXELFORMAT *provided){ /* Some flags must be present in both or neither for a match. */ static const DWORD must_match = DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 | DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_FOURCC | DDPF_ZBUFFER | DDPF_STENCILBUFFER; if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags) return FALSE; if ((requested->dwFlags & must_match) != (provided->dwFlags & must_match)) return FALSE; if (requested->dwFlags & DDPF_FOURCC) if (requested->dwFourCC != provided->dwFourCC) return FALSE; if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_ALPHA |DDPF_LUMINANCE|DDPF_BUMPDUDV)) if (requested->u1.dwRGBBitCount != provided->u1.dwRGBBitCount) return FALSE; if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER |DDPF_LUMINANCE|DDPF_BUMPDUDV)) if (requested->u2.dwRBitMask != provided->u2.dwRBitMask) return FALSE; if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_ZBUFFER|DDPF_BUMPDUDV)) if (requested->u3.dwGBitMask != provided->u3.dwGBitMask) return FALSE; /* I could be wrong about the bumpmapping. MSDN docs are vague. */ if (requested->dwFlags & (DDPF_RGB|DDPF_YUV|DDPF_STENCILBUFFER |DDPF_BUMPDUDV)) if (requested->u4.dwBBitMask != provided->u4.dwBBitMask) return FALSE; if (requested->dwFlags & (DDPF_ALPHAPIXELS|DDPF_ZPIXELS)) if (requested->u5.dwRGBAlphaBitMask != provided->u5.dwRGBAlphaBitMask) return FALSE; return TRUE;}BOOL Main_DirectDraw_DDSD_Match(const DDSURFACEDESC2* requested, const DDSURFACEDESC2* provided){ struct compare_info { DWORD flag; ptrdiff_t offset; size_t size; };#define CMP(FLAG, FIELD) \ { DDSD_##FLAG, offsetof(DDSURFACEDESC2, FIELD), \ sizeof(((DDSURFACEDESC2 *)(NULL))->FIELD) } static const struct compare_info compare[] = { CMP(ALPHABITDEPTH, dwAlphaBitDepth), CMP(BACKBUFFERCOUNT, dwBackBufferCount), CMP(CAPS, ddsCaps), CMP(CKDESTBLT, ddckCKDestBlt), CMP(CKDESTOVERLAY, u3.ddckCKDestOverlay), CMP(CKSRCBLT, ddckCKSrcBlt), CMP(CKSRCOVERLAY, ddckCKSrcOverlay), CMP(HEIGHT, dwHeight), CMP(LINEARSIZE, u1.dwLinearSize), CMP(LPSURFACE, lpSurface), CMP(MIPMAPCOUNT, u2.dwMipMapCount), CMP(PITCH, u1.lPitch), /* PIXELFORMAT: manual */ CMP(REFRESHRATE, u2.dwRefreshRate), CMP(TEXTURESTAGE, dwTextureStage), CMP(WIDTH, dwWidth), /* ZBUFFERBITDEPTH: "obsolete" */ };#undef CMP int i; if ((requested->dwFlags & provided->dwFlags) != requested->dwFlags) return FALSE; for (i=0; i < sizeof(compare)/sizeof(compare[0]); i++) { if (requested->dwFlags & compare[i].flag && memcmp((const char *)provided + compare[i].offset, (const char *)requested + compare[i].offset, compare[i].size) != 0) return FALSE; } if (requested->dwFlags & DDSD_PIXELFORMAT) { if (!Main_DirectDraw_DDPIXELFORMAT_Match(&requested->u4.ddpfPixelFormat, &provided->u4.ddpfPixelFormat)) return FALSE; } return TRUE;}#define DDENUMSURFACES_SEARCHTYPE (DDENUMSURFACES_CANBECREATED|DDENUMSURFACES_DOESEXIST)#define DDENUMSURFACES_MATCHTYPE (DDENUMSURFACES_ALL|DDENUMSURFACES_MATCH|DDENUMSURFACES_NOMATCH)/* This should be extended so that it can be used by * IDirectDrawSurface7::EnumAttachedSurfaces. */HRESULTMain_DirectDraw_EnumExistingSurfaces(IDirectDrawImpl *This, DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD2, LPVOID context, LPDDENUMSURFACESCALLBACK7 callback){ IDirectDrawSurfaceImpl *surf; BOOL all, nomatch; /* A NULL lpDDSD2 is permitted if we are enumerating all surfaces anyway */ if (lpDDSD2 == NULL && !(dwFlags & DDENUMSURFACES_ALL)) return DDERR_INVALIDPARAMS; all = dwFlags & DDENUMSURFACES_ALL; nomatch = dwFlags & DDENUMSURFACES_NOMATCH; for (surf = This->surfaces; surf != NULL; surf = surf->next_ddraw) { if (all || (nomatch != Main_DirectDraw_DDSD_Match(lpDDSD2, &surf->surface_desc))) { LPDIRECTDRAWSURFACE7 surface = ICOM_INTERFACE(surf, IDirectDrawSurface7); /* BOGUS! Violates COM rules, but MSDN says so. */ IDirectDrawSurface7_AddRef(surface); if (callback(surface, &surf->surface_desc, context) == DDENUMRET_CANCEL) break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -