// DirectDrawSurface2 Calls void DDCreateSurface ( LPDIRECTDRAW2 pExistingDirectDraw, DDSURFACEDESC *pNewSurfaceDesc, LPDIRECTDRAWSURFACE *ppNewSurface1, LPDIRECTDRAWSURFACE2 *ppNewSurface2 ) { Assert ( pExistingDirectDraw != NULL ); Assert ( pNewSurfaceDesc != NULL ); Assert ( ppNewSurface1 != NULL ); Assert ( ppNewSurface2 != NULL ); // create the directdraw surface ATTEMPT ( IDirectDraw2_CreateSurface ( pExistingDirectDraw, pNewSurfaceDesc, ppNewSurface1, NULL ) ); //get the direct draw surface 2 interface ATTEMPT ( IDirectDrawSurface_QueryInterface ( *ppNewSurface1, &IID_IDirectDrawSurface2, (LPVOID*) ppNewSurface2 ) ); }
/** * Create and initialize display according to preferences specified in the vout * thread fields. */ static int DirectXOpenDisplay(vout_display_t *vd) { vout_display_sys_t *sys = vd->sys; HRESULT hr; /* Now get the primary surface. This surface is what you actually see * on your screen */ DDSURFACEDESC ddsd; ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; LPDIRECTDRAWSURFACE display; hr = IDirectDraw2_CreateSurface(sys->ddobject, &ddsd, &display, NULL); if (hr != DD_OK) { msg_Err(vd, "cannot get primary surface (error %li)", hr); return VLC_EGENERIC; } void *ptr; hr = IDirectDrawSurface_QueryInterface(display, &IID_IDirectDrawSurface2, &ptr); /* Release the old interface */ IDirectDrawSurface_Release(display); if (hr != DD_OK) { msg_Err(vd, "cannot query IDirectDrawSurface2 interface (error %li)", hr); sys->display = NULL; return VLC_EGENERIC; } sys->display = ptr; /* The clipper will be used only in non-overlay mode */ DirectXCreateClipper(vd); /* Make sure the colorkey will be painted */ sys->i_colorkey = 1; sys->i_rgb_colorkey = DirectXFindColorkey(vd, &sys->i_colorkey); return VLC_SUCCESS; }
int d3d_init_device(GUID guid) { HRESULT res; DDSURFACEDESC ddsd; if (!d3d_initialized) return -1; // Grab back buffer. res = IDirectDrawSurface_QueryInterface(_lpDDSBack, &_3DGUID, &_lpD3DDev); if (res != DD_OK) { WRITELOG((LogFile, "Unable to retrieve device from back buffer. %x\n",res)); return d3d_handle_error(res); } // Enumerate texture formats Assert(d3dCaps.tmap_acc == TRUE); d3dCaps.tmap_formats = 0; if (d3d_enum_texformats()) return -1; return 0; }
/** * Create an YUV overlay or RGB surface for the video. * * The best method of display is with an YUV overlay because the YUV->RGB * conversion is done in hardware. * You can also create a plain RGB surface. * (Maybe we could also try an RGB overlay surface, which could have hardware * scaling and which would also be faster in window mode because you don't * need to do any blitting to the main display...) */ static int DirectXCreateSurface(vout_display_t *vd, LPDIRECTDRAWSURFACE2 *surface, const video_format_t *fmt, DWORD fourcc, bool use_overlay, bool use_sysmem, int backbuffer_count) { vout_display_sys_t *sys = vd->sys; DDSURFACEDESC ddsd; ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH; ddsd.dwWidth = fmt->i_width; ddsd.dwHeight = fmt->i_height; if (fourcc) { ddsd.dwFlags |= DDSD_PIXELFORMAT; ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; ddsd.ddpfPixelFormat.dwFourCC = fourcc; } if (use_overlay) { ddsd.dwFlags |= DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY; if (backbuffer_count > 0) ddsd.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP; if (backbuffer_count > 0) { ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = backbuffer_count; } } else { ddsd.dwFlags |= DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; if (use_sysmem) ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; else ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY; } /* Create the video surface */ LPDIRECTDRAWSURFACE surface_v1; if (IDirectDraw2_CreateSurface(sys->ddobject, &ddsd, &surface_v1, NULL) != DD_OK) return VLC_EGENERIC; /* Now that the surface is created, try to get a newer DirectX interface */ HRESULT hr = IDirectDrawSurface_QueryInterface(surface_v1, &IID_IDirectDrawSurface2, (LPVOID *)surface); IDirectDrawSurface_Release(surface_v1); if (hr != DD_OK) { msg_Err(vd, "cannot query IDirectDrawSurface2 interface (error %li)", hr); return VLC_EGENERIC; } if (use_overlay) { /* Check the overlay is useable as some graphics cards allow creating * several overlays but only one can be used at one time. */ if (DirectXUpdateOverlay(vd, *surface)) { IDirectDrawSurface2_Release(*surface); msg_Err(vd, "overlay unuseable (might already be in use)"); return VLC_EGENERIC; } } return VLC_SUCCESS; }
static int ddraw_create_surfaces(win_window_info *window) { dd_info *dd = window->drawdata; HRESULT result; // make a description of the primary surface memset(&dd->primarydesc, 0, sizeof(dd->primarydesc)); dd->primarydesc.dwSize = sizeof(dd->primarydesc); dd->primarydesc.dwFlags = DDSD_CAPS; dd->primarydesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // for triple-buffered full screen mode, allocate flipping surfaces if (window->fullscreen && video_config.triplebuf) { dd->primarydesc.dwFlags |= DDSD_BACKBUFFERCOUNT; dd->primarydesc.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX; dd->primarydesc.dwBackBufferCount = 2; } // create the primary surface and report errors result = create_surface(dd, &dd->primarydesc, &dd->primary, "primary"); if (result != DD_OK) goto error; // full screen mode: get the back surface dd->back = NULL; if (window->fullscreen && video_config.triplebuf) { DDSCAPS2 caps = { DDSCAPS_BACKBUFFER }; result = IDirectDrawSurface7_GetAttachedSurface(dd->primary, &caps, &dd->back); if (result != DD_OK) { mame_printf_verbose("DirectDraw: Error %08X getting attached back surface\n", (int)result); goto error; } } // now make a description of our blit surface, based on the primary surface if (dd->blitwidth == 0 || dd->blitheight == 0) compute_blit_surface_size(window); dd->blitdesc = dd->primarydesc; dd->blitdesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS; dd->blitdesc.dwWidth = dd->blitwidth; dd->blitdesc.dwHeight = dd->blitheight; dd->blitdesc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; // then create the blit surface, fall back to system memory if video mem doesn't work result = create_surface(dd, &dd->blitdesc, &dd->blit, "blit"); if (result != DD_OK) { dd->blitdesc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY; result = create_surface(dd, &dd->blitdesc, &dd->blit, "blit"); } if (result != DD_OK) goto error; // create a memory buffer for offscreen drawing if (dd->membuffersize < dd->blitwidth * dd->blitheight * 4) { dd->membuffersize = dd->blitwidth * dd->blitheight * 4; dd->membuffer = realloc(dd->membuffer, dd->membuffersize); } if (dd->membuffer == NULL) goto error; #ifdef MESS // create a clipper for all modes, since MESS has dialogs if (create_clipper(window)) goto error; #else // create a clipper for windowed mode if (!window->fullscreen && create_clipper(window)) goto error; #endif // full screen mode: set the gamma if (window->fullscreen) { // only set the gamma if it's not 1.0f float brightness = options_get_float(mame_options(), WINOPTION_FULLSCREENBRIGHTNESS); float contrast = options_get_float(mame_options(), WINOPTION_FULLLSCREENCONTRAST); float gamma = options_get_float(mame_options(), WINOPTION_FULLSCREENGAMMA); if (brightness != 1.0f || contrast != 1.0f || gamma != 1.0f) { // see if we can get a GammaControl object result = IDirectDrawSurface_QueryInterface(dd->primary, &IID_IDirectDrawGammaControl, (void **)&dd->gamma); if (result != DD_OK) { mame_printf_warning("DirectDraw: Warning - device does not support full screen gamma correction.\n"); dd->gamma = NULL; } // proceed if we can if (dd->gamma != NULL) { DDGAMMARAMP ramp; int i; // create a standard ramp and set it for (i = 0; i < 256; i++) ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, gamma) << 8; // attempt to set it result = IDirectDrawGammaControl_SetGammaRamp(dd->gamma, 0, &ramp); if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X attempting to set gamma correction.\n", (int)result); } } } // force some updates update_outer_rects(dd); return 0; error: ddraw_delete_surfaces(window); return 1; }
static void test_IDirectDrawStreamSample(void) { DDSURFACEDESC desc = { sizeof(desc) }; IAMMultiMediaStream *pams; HRESULT hr; IMediaStream *pvidstream = NULL; IDirectDrawMediaStream *pddstream = NULL; IDirectDrawStreamSample *pddsample = NULL; IDirectDrawSurface7 *surface7; IDirectDrawSurface *surface, *surface2; IDirectDraw *ddraw, *ddraw2; IDirectDraw7 *ddraw7; RECT rect; if (!(pams = create_ammultimediastream())) return; if (!create_directdraw()) { IAMMultiMediaStream_Release(pams); return; } hr = IAMMultiMediaStream_Initialize(pams, STREAMTYPE_READ, 0, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IAMMultiMediaStream_AddMediaStream(pams, (IUnknown*)pdd7, &MSPID_PrimaryVideo, 0, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IAMMultiMediaStream_GetMediaStream(pams, &MSPID_PrimaryVideo, &pvidstream); ok(hr == S_OK, "got 0x%08x\n", hr); if (FAILED(hr)) goto error; hr = IMediaStream_QueryInterface(pvidstream, &IID_IDirectDrawMediaStream, (LPVOID*)&pddstream); ok(hr == S_OK, "got 0x%08x\n", hr); if (FAILED(hr)) goto error; hr = IDirectDrawMediaStream_GetDirectDraw(pddstream, &ddraw); ok(hr == S_OK, "got 0x%08x\n", hr); hr = IDirectDrawMediaStream_GetDirectDraw(pddstream, &ddraw2); ok(hr == S_OK, "got 0x%08x\n", hr); ok(ddraw == ddraw2, "got %p, %p\n", ddraw, ddraw2); hr = IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw7, (void**)&ddraw7); ok(hr == S_OK, "got 0x%08x\n", hr); IDirectDraw7_Release(ddraw7); IDirectDraw_Release(ddraw2); IDirectDraw_Release(ddraw); hr = IDirectDrawMediaStream_CreateSample(pddstream, NULL, NULL, 0, &pddsample); ok(hr == S_OK, "got 0x%08x\n", hr); surface = NULL; hr = IDirectDrawStreamSample_GetSurface(pddsample, &surface, &rect); ok(hr == S_OK, "got 0x%08x\n", hr); ok(surface != NULL, "got %p\n", surface); hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirectDrawSurface7, (void**)&surface7); ok(hr == S_OK, "got 0x%08x\n", hr); IDirectDrawSurface7_Release(surface7); hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc); ok(hr == S_OK, "got 0x%08x\n", hr); ok(desc.dwWidth == 100, "width %d\n", desc.dwWidth); ok(desc.dwHeight == 100, "height %d\n", desc.dwHeight); ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "format flags %08x\n", desc.ddpfPixelFormat.dwFlags); ok(desc.ddpfPixelFormat.dwRGBBitCount, "dwRGBBitCount %d\n", desc.ddpfPixelFormat.dwRGBBitCount); IDirectDrawSurface_Release(surface); IDirectDrawStreamSample_Release(pddsample); hr = IDirectDrawSurface7_QueryInterface(pdds7, &IID_IDirectDrawSurface, (void**)&surface); ok(hr == S_OK, "got 0x%08x\n", hr); EXPECT_REF(surface, 1); hr = IDirectDrawMediaStream_CreateSample(pddstream, surface, NULL, 0, &pddsample); ok(hr == S_OK, "got 0x%08x\n", hr); EXPECT_REF(surface, 2); surface2 = NULL; memset(&rect, 0, sizeof(rect)); hr = IDirectDrawStreamSample_GetSurface(pddsample, &surface2, &rect); ok(hr == S_OK, "got 0x%08x\n", hr); ok(surface == surface2, "got %p\n", surface2); ok(rect.right > 0 && rect.bottom > 0, "got %d, %d\n", rect.right, rect.bottom); EXPECT_REF(surface, 3); IDirectDrawSurface_Release(surface2); hr = IDirectDrawStreamSample_GetSurface(pddsample, NULL, NULL); ok(hr == S_OK, "got 0x%08x\n", hr); IDirectDrawStreamSample_Release(pddsample); IDirectDrawSurface_Release(surface); error: if (pddstream) IDirectDrawMediaStream_Release(pddstream); if (pvidstream) IMediaStream_Release(pvidstream); release_directdraw(); IAMMultiMediaStream_Release(pams); }
/* get_dx_ver: * returns the DirectX dx_version number: * * 0 no DirectX installed * 0x100 DirectX 1 installed * 0x200 DirectX 2 installed * 0x300 DirectX 3 installed * 0x500 at least DirectX 5 installed * 0x600 at least DirectX 6 installed * 0x700 at least DirectX 7 installed */ int get_dx_ver(void) { HRESULT hr; HINSTANCE ddraw_hinst = NULL; HINSTANCE dinput_hinst = NULL; HINSTANCE dsetup_hinst = NULL; LPDIRECTDRAW directdraw = NULL; LPDIRECTDRAW2 directdraw2 = NULL; DIRECTDRAWCREATE DirectDrawCreate = NULL; DIRECTINPUTCREATE DirectInputCreate = NULL; DSETUPCREATE DSetupCreate = NULL; OSVERSIONINFO os_version; LPDIRECTDRAWSURFACE ddraw_surf = NULL; LPDIRECTDRAWSURFACE3 ddraw_surf3 = NULL; DWORD dsetup_revision; DWORD dsetup_version; INT dsetup_result; #if DIRECTX_SDK_VERSION >= 0x600 LPDIRECTDRAWSURFACE4 ddraw_surf4 = NULL; #if DIRECTX_SDK_VERSION >= 0x700 LPDIRECTDRAWSURFACE7 ddraw_surf7 = NULL; #endif #endif DDSURFACEDESC ddraw_surf_desc; LPVOID temp; int dx_version = 0; /* first get the Windows platform */ os_version.dwOSVersionInfoSize = sizeof(os_version); if (!GetVersionEx(&os_version)) return dx_version; if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT) { /* NT is easy... NT 4.0 is DX2, 4.0 SP3 is DX3, 5.0 is DX5 at least * and no DX on earlier versions */ if (os_version.dwMajorVersion < 4) { /* No DX on NT 3.51 or earlier */ return dx_version; } /* First check for DX 8 and 9 */ dsetup_hinst = LoadLibrary( "DSETUP.DLL" ); if ( dsetup_hinst ) { DSetupCreate = (DSETUPCREATE)GetProcAddress(dsetup_hinst, "DirectXSetupGetVersion"); if ( DSetupCreate ) { dsetup_result = DSetupCreate( &dsetup_version, &dsetup_revision ); // returns 0 on failure if ( dsetup_result ) { switch (dsetup_version) { case 0x00040005: dx_version = 0x500; break; case 0x00040006: dx_version = 0x600; break; case 0x00040007: dx_version = 0x700; break; case 0x00040008: /* v8.x */ dx_version = 0x800; switch (dsetup_revision) { case 0x0001032A: case 0x00010371: dx_version = 0x810; /* 8.1 */ dx_version = 0x810; /* 8.1 */ break; case 0x00010385: dx_version = 0x81a; /* 8.1a or b (stupid MS...) */ break; case 0x00020386: dx_version = 0x820; /* 8.2 */ break; default: dx_version = 0x800; /* 8.0 */ } /* switch (dsetup_revision) */ case 0x00040009: switch (dsetup_revision) { case 0x00000384: dx_version = 0x900; /* 9.0 */ break; case 0x00000385: dx_version = 0x90a; /* 9.0a */ break; case 0x00000386: dx_version = 0x90b; /* 9.0b */ break; case 0x00000387: dx_version = 0x90b; /* 9.0(b or c) */ break; case 0x00000388: dx_version = 0x90c; /* 9.0c */ break; default: dx_version = 0x900; } /* switch (dsetup_revision) */ } /* switch (dsetup_version) */ } } FreeLibrary( dsetup_hinst ); if ( dx_version ) return dx_version; } if (os_version.dwMajorVersion == 4) { /* NT4 up to SP2 is DX2, and SP3 onwards is DX3, so we are at least DX2 */ dx_version = 0x200; /* we are not supposed to be able to tell which SP we are on, so check for DInput */ dinput_hinst = LoadLibrary("DINPUT.DLL"); if (!dinput_hinst) { /* no DInput... must be DX2 on NT 4 pre-SP3 */ OutputDebugString("Couldn't LoadLibrary DInput\r\n"); return dx_version; } DirectInputCreate = (DIRECTINPUTCREATE) GetProcAddress(dinput_hinst, "DirectInputCreateA"); FreeLibrary(dinput_hinst); if (!DirectInputCreate) { /* no DInput... must DX2 on NT 4 pre-SP3 */ return dx_version; } /* DX3 on NT4 SP3 or higher */ dx_version = 0x300; return dx_version; } /* it's at least NT 5 and it's DX5a or higher: * drop through to Win9x tests for a test of DDraw */ } /* now we know we are in Windows 9x (or maybe 3.1), so anything's possible; * first see if DDRAW.DLL even exists. */ ddraw_hinst = LoadLibrary("DDRAW.DLL"); if (!ddraw_hinst) { dx_version = 0; goto End; } /* see if we can create the DirectDraw object */ DirectDrawCreate = (DIRECTDRAWCREATE) GetProcAddress(ddraw_hinst, "DirectDrawCreate"); if (!DirectDrawCreate) { dx_version = 0; goto End; } hr = DirectDrawCreate(NULL, &directdraw, NULL); if (FAILED(hr)) { dx_version = 0; goto End; } /* so DirectDraw exists, we are at least DX1 */ dx_version = 0x100; /* let's see if IDirectDraw2 exists */ hr = IDirectDraw_QueryInterface(directdraw, &IID_IDirectDraw2, &temp); if (FAILED(hr)) { /* no IDirectDraw2 exists... must be DX1 */ goto End; } directdraw2 = temp; /* IDirectDraw2 exists... must be at least DX2 */ IDirectDraw2_Release(directdraw2); dx_version = 0x200; /* see if we can create the DirectInput object */ dinput_hinst = LoadLibrary("DINPUT.DLL"); if (!dinput_hinst) { /* no DInput... must be DX2 */ goto End; } DirectInputCreate = (DIRECTINPUTCREATE) GetProcAddress(dinput_hinst, "DirectInputCreateA"); FreeLibrary(dinput_hinst); if (!DirectInputCreate) { /* no DInput... must be DX2 */ goto End; } /* DirectInputCreate exists; that's enough to tell us that we are at least DX3 */ dx_version = 0x300; /* we can tell if DX5 is present by checking for the existence of IDirectDrawSurface3; * first we need a surface to QI off of */ memset(&ddraw_surf_desc, 0, sizeof(ddraw_surf_desc)); ddraw_surf_desc.dwSize = sizeof(ddraw_surf_desc); ddraw_surf_desc.dwFlags = DDSD_CAPS; ddraw_surf_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; hr = IDirectDraw_SetCooperativeLevel(directdraw, NULL, DDSCL_NORMAL); if (FAILED(hr)) { /* failure: this means DDraw isn't properly installed */ dx_version = 0; goto End; } hr = IDirectDraw_CreateSurface(directdraw, &ddraw_surf_desc, &ddraw_surf, NULL); if (FAILED(hr)) { /* failure: this means DDraw isn't properly installed */ dx_version = 0; goto End; } /* try for the IDirectDrawSurface3 interface; if it works, we're on DX5 at least */ hr = IDirectDrawSurface_QueryInterface(ddraw_surf, &IID_IDirectDrawSurface3, &temp); if (FAILED(hr)) goto End; ddraw_surf3 = temp; /* QI for IDirectDrawSurface3 succeeded; we must be at least DX5 */ dx_version = 0x500; #if DIRECTX_SDK_VERSION >= 0x600 /* try for the IDirectDrawSurface4 interface; if it works, we're on DX6 at least */ hr = IDirectDrawSurface_QueryInterface(ddraw_surf, &IID_IDirectDrawSurface4, (LPVOID *) &ddraw_surf4); if (FAILED(hr)) goto End; /* QI for IDirectDrawSurface4 succeeded; we must be at least DX6 */ dx_version = 0x600; #if DIRECTX_SDK_VERSION >= 0x700 /* try for the IDirectDrawSurface7 interface; if it works, we're on DX7 at least */ hr = IDirectDrawSurface_QueryInterface(ddraw_surf, &IID_IDirectDrawSurface7, (LPVOID *) &ddraw_surf7); if (FAILED(hr)) goto End; /* QI for IDirectDrawSurface7 succeeded; we must be at least DX7 */ dx_version = 0x700; #endif #endif End: if (directdraw) IDirectDraw_Release(directdraw); if (ddraw_hinst) FreeLibrary(ddraw_hinst); return dx_version; }
HRESULT d3drm_device_init(struct d3drm_device *device, UINT version, IDirectDraw *ddraw, IDirectDrawSurface *surface, BOOL create_z_surface) { DDSCAPS caps = { DDSCAPS_ZBUFFER }; IDirectDrawSurface *ds = NULL; IDirect3DDevice *device1 = NULL; IDirect3DDevice2 *device2 = NULL; IDirect3D2 *d3d2 = NULL; DDSURFACEDESC desc, surface_desc; HRESULT hr; device->ddraw = ddraw; IDirectDraw_AddRef(ddraw); IDirect3DRM_AddRef(device->d3drm); device->render_target = surface; IDirectDrawSurface_AddRef(surface); desc.dwSize = sizeof(desc); hr = IDirectDrawSurface_GetSurfaceDesc(surface, &desc); if (FAILED(hr)) return hr; if (!(desc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) return DDERR_INVALIDCAPS; hr = IDirectDrawSurface_GetAttachedSurface(surface, &caps, &ds); if (SUCCEEDED(hr)) { create_z_surface = FALSE; IDirectDrawSurface_Release(ds); ds = NULL; } if (create_z_surface) { memset(&surface_desc, 0, sizeof(surface_desc)); surface_desc.dwSize = sizeof(surface_desc); surface_desc.dwFlags = DDSD_CAPS | DDSD_ZBUFFERBITDEPTH | DDSD_WIDTH | DDSD_HEIGHT; surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; surface_desc.u2.dwZBufferBitDepth = 16; surface_desc.dwWidth = desc.dwWidth; surface_desc.dwHeight = desc.dwHeight; hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &ds, NULL); if (FAILED(hr)) return hr; hr = IDirectDrawSurface_AddAttachedSurface(surface, ds); IDirectDrawSurface_Release(ds); if (FAILED(hr)) return hr; } if (version == 1) hr = IDirectDrawSurface_QueryInterface(surface, &IID_IDirect3DRGBDevice, (void **)&device1); else { IDirectDraw_QueryInterface(ddraw, &IID_IDirect3D2, (void**)&d3d2); hr = IDirect3D2_CreateDevice(d3d2, &IID_IDirect3DRGBDevice, surface, &device2); IDirect3D2_Release(d3d2); } if (FAILED(hr)) { IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds); return hr; } if (version != 1) { hr = IDirect3DDevice2_QueryInterface(device2, &IID_IDirect3DDevice, (void**)&device1); IDirect3DDevice2_Release(device2); if (FAILED(hr)) { IDirectDrawSurface_DeleteAttachedSurface(surface, 0, ds); return hr; } } device->device = device1; device->width = desc.dwWidth; device->height = desc.dwHeight; return hr; }
/* create_directdraw2_surface: * Wrapper around DirectDraw2::CreateSurface taking the surface characteristics * as parameters. Returns a DirectDrawSurface2 interface if successful. */ static LPDIRECTDRAWSURFACE2 create_directdraw2_surface(int w, int h, LPDDPIXELFORMAT pixel_format, int type, int n_backbuffers) { DDSURFACEDESC ddsurf_desc; LPDIRECTDRAWSURFACE ddsurf1; LPVOID ddsurf2; HRESULT hr; /* describe surface characteristics */ memset(&ddsurf_desc, 0, sizeof(DDSURFACEDESC)); ddsurf_desc.dwSize = sizeof(DDSURFACEDESC); ddsurf_desc.dwFlags = DDSD_CAPS; switch (type) { case DDRAW_SURFACE_PRIMARY: ddsurf_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; _TRACE(PREFIX_I "Creating primary surface..."); break; case DDRAW_SURFACE_OVERLAY: ddsurf_desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OVERLAY; ddsurf_desc.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH; ddsurf_desc.dwHeight = h; ddsurf_desc.dwWidth = w; if (pixel_format) { /* use pixel format */ ddsurf_desc.dwFlags |= DDSD_PIXELFORMAT; ddsurf_desc.ddpfPixelFormat = *pixel_format; } _TRACE(PREFIX_I "Creating overlay surface..."); break; case DDRAW_SURFACE_VIDEO: ddsurf_desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN; ddsurf_desc.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH; ddsurf_desc.dwHeight = h; ddsurf_desc.dwWidth = w; _TRACE(PREFIX_I "Creating video surface..."); break; case DDRAW_SURFACE_SYSTEM: ddsurf_desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN; ddsurf_desc.dwFlags |= DDSD_HEIGHT | DDSD_WIDTH; ddsurf_desc.dwHeight = h; ddsurf_desc.dwWidth = w; if (pixel_format) { /* use pixel format */ ddsurf_desc.dwFlags |= DDSD_PIXELFORMAT; ddsurf_desc.ddpfPixelFormat = *pixel_format; } _TRACE(PREFIX_I "Creating system surface..."); break; default: _TRACE(PREFIX_E "Unknown surface type\n"); return NULL; } /* set backbuffer requirements */ if (n_backbuffers > 0) { ddsurf_desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX | DDSCAPS_FLIP; ddsurf_desc.dwFlags |= DDSD_BACKBUFFERCOUNT; ddsurf_desc.dwBackBufferCount = n_backbuffers; _TRACE("...with %d backbuffer(s)\n", n_backbuffers); } /* create the surface */ hr = IDirectDraw2_CreateSurface(directdraw, &ddsurf_desc, &ddsurf1, NULL); if (FAILED(hr)) { _TRACE(PREFIX_E "Unable to create the surface (%s)\n", dd_err(hr)); return NULL; } /* retrieve the DirectDrawSurface2 interface */ hr = IDirectDrawSurface_QueryInterface(ddsurf1, &IID_IDirectDrawSurface2, &ddsurf2); /* there is a bug in the COM part of DirectX 3: * If we release the DirectSurface interface, the actual * object is also released. It is fixed in DirectX 5. */ if (_dx_ver >= 0x500) IDirectDrawSurface_Release(ddsurf1); if (FAILED(hr)) { _TRACE(PREFIX_E "Unable to retrieve the DirectDrawSurface2 interface (%s)\n", dd_err(hr)); return NULL; } return (LPDIRECTDRAWSURFACE2)ddsurf2; }
static void GetDCTest_main(DDSURFACEDESC *ddsd, DDSURFACEDESC2 *ddsd2, void (*testfunc)(IDirectDrawSurface *surf, int ddsdver)) { IDirectDrawSurface *surf; IDirectDrawSurface2 *surf2; IDirectDrawSurface2 *surf3; IDirectDrawSurface4 *surf4; HRESULT hr; IDirectDraw *dd1 = createDD(); IDirectDraw2 *dd2; IDirectDraw3 *dd3; IDirectDraw4 *dd4; hr = IDirectDraw_CreateSurface(dd1, ddsd, &surf, NULL); if (hr == DDERR_UNSUPPORTEDMODE) { win_skip("Unsupported mode\n"); return; } ok(hr == DD_OK, "IDirectDraw_CreateSurface failed: 0x%08x\n", hr); testfunc(surf, 1); IDirectDrawSurface_Release(surf); hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw2, (void **) &dd2); ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr); hr = IDirectDraw2_CreateSurface(dd2, ddsd, &surf, NULL); ok(hr == DD_OK, "IDirectDraw2_CreateSurface failed: 0x%08x\n", hr); testfunc(surf, 1); hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface2, (void **) &surf2); ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr); testfunc((IDirectDrawSurface *) surf2, 1); IDirectDrawSurface2_Release(surf2); IDirectDrawSurface_Release(surf); IDirectDraw2_Release(dd2); hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw3, (void **) &dd3); ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr); hr = IDirectDraw3_CreateSurface(dd3, ddsd, &surf, NULL); ok(hr == DD_OK, "IDirectDraw3_CreateSurface failed: 0x%08x\n", hr); testfunc(surf, 1); hr = IDirectDrawSurface_QueryInterface(surf, &IID_IDirectDrawSurface3, (void **) &surf3); ok(hr == DD_OK, "IDirectDrawSurface_QueryInterface failed: 0x%08x\n", hr); testfunc((IDirectDrawSurface *) surf3, 1); IDirectDrawSurface3_Release(surf3); IDirectDrawSurface_Release(surf); IDirectDraw3_Release(dd3); hr = IDirectDraw_QueryInterface(dd1, &IID_IDirectDraw4, (void **) &dd4); ok(hr == DD_OK, "IDirectDraw_QueryInterface failed: 0x%08x\n", hr); surf = NULL; hr = IDirectDraw4_CreateSurface(dd4, ddsd2, &surf4, NULL); ok(hr == DD_OK, "IDirectDraw4_CreateSurface failed: 0x%08x\n", hr); testfunc((IDirectDrawSurface *) surf4, 2); IDirectDrawSurface4_Release(surf4); IDirectDraw4_Release(dd4); IDirectDraw_Release(dd1); }
int renderer_dd::ddraw_create_surfaces() { HRESULT result; // make a description of the primary surface memset(&primarydesc, 0, sizeof(primarydesc)); primarydesc.dwSize = sizeof(primarydesc); primarydesc.dwFlags = DDSD_CAPS; primarydesc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; // for triple-buffered full screen mode, allocate flipping surfaces if (window().fullscreen() && video_config.triplebuf) { primarydesc.dwFlags |= DDSD_BACKBUFFERCOUNT; primarydesc.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX; primarydesc.dwBackBufferCount = 2; } // create the primary surface and report errors result = create_surface(&primarydesc, &primary, "primary"); if (result != DD_OK) goto error; // full screen mode: get the back surface back = NULL; if (window().fullscreen() && video_config.triplebuf) { DDSCAPS2 caps = { DDSCAPS_BACKBUFFER }; result = IDirectDrawSurface7_GetAttachedSurface(primary, &caps, &back); if (result != DD_OK) { osd_printf_verbose("DirectDraw: Error %08X getting attached back surface\n", (int)result); goto error; } } // now make a description of our blit surface, based on the primary surface if (blitwidth == 0 || blitheight == 0) compute_blit_surface_size(); blitdesc = primarydesc; blitdesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS; blitdesc.dwWidth = blitwidth; blitdesc.dwHeight = blitheight; blitdesc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; // then create the blit surface, fall back to system memory if video mem doesn't work result = create_surface(&blitdesc, &blit, "blit"); if (result != DD_OK) { blitdesc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY; result = create_surface(&blitdesc, &blit, "blit"); } if (result != DD_OK) goto error; // create a memory buffer for offscreen drawing if (membuffersize < blitwidth * blitheight * 4) { membuffersize = blitwidth * blitheight * 4; global_free_array(membuffer); membuffer = global_alloc_array_nothrow(UINT8, membuffersize); } if (membuffer == NULL) goto error; // create a clipper for windowed mode if (!window().fullscreen() && create_clipper()) goto error; // full screen mode: set the gamma if (window().fullscreen()) { // only set the gamma if it's not 1.0f windows_options &options = downcast<windows_options &>(window().machine().options()); float brightness = options.full_screen_brightness(); float contrast = options.full_screen_contrast(); float fgamma = options.full_screen_gamma(); if (brightness != 1.0f || contrast != 1.0f || fgamma != 1.0f) { // see if we can get a GammaControl object result = IDirectDrawSurface_QueryInterface(primary, WRAP_REFIID(IID_IDirectDrawGammaControl), (void **)&gamma); if (result != DD_OK) { osd_printf_warning("DirectDraw: Warning - device does not support full screen gamma correction.\n"); this->gamma = NULL; } // proceed if we can if (this->gamma != NULL) { DDGAMMARAMP ramp; int i; // create a standard ramp and set it for (i = 0; i < 256; i++) ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, fgamma) << 8; // attempt to set it result = IDirectDrawGammaControl_SetGammaRamp(this->gamma, 0, &ramp); if (result != DD_OK) osd_printf_verbose("DirectDraw: Error %08X attempting to set gamma correction.\n", (int)result); } } } // force some updates update_outer_rects(); return 0; error: ddraw_delete_surfaces(); return 1; }