/***************************************************************************** * get_sub_mimaplevel * * Helper function that returns the next mipmap level * * tex_ptr: Surface of which to return the next level * *****************************************************************************/ static IDirectDrawSurfaceImpl * get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr) { /* Now go down the mipmap chain to the next surface */ static const DDSCAPS2 mipmap_caps = { DDSCAPS_MIPMAP | DDSCAPS_TEXTURE, 0, 0, 0 }; LPDIRECTDRAWSURFACE7 next_level; IDirectDrawSurfaceImpl *surf_ptr; HRESULT hr; hr = IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(tex_ptr, IDirectDrawSurface7), (DDSCAPS2 *) &mipmap_caps, &next_level); if (FAILED(hr)) return NULL; surf_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, next_level); IDirectDrawSurface7_Release(next_level); return surf_ptr; }
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; }
int test_video_resolution ( int width, int height, int depth ) { unsigned int ddrval; DDSURFACEDESC2 ddsd; DDSCAPS2 caps; // // Set the video mode // { int parms[3]; parms[0] = width; parms[1] = height; parms[2] = depth; ddrval = system_thread_function ( ddraw_internal_set_display_mode, parms ); } if ( ddrval != DD_OK ) { debug_log ( "Unable to set display resolution: %d, %d, %d: %s", width, height, depth, get_ddraw_error_message ( ddrval ) ); return ( FALSE ); } // // Release any previous pointers // release_ddraw_surface_pointers (); // // Create the primary surface // memset ( &ddsd, 0, sizeof ( ddsd ) ); ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE; if ( ddraw.use_double_buffer ) { ddsd.dwFlags |= DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = 1; ddsd.ddsCaps.dwCaps |= DDSCAPS_FLIP | DDSCAPS_COMPLEX; } #ifdef _WIN32 ddrval = IDirectDraw7_CreateSurface ( ddraw.ddraw, &ddsd, &ddraw.lpFrontBuffer, NULL); if ( ddrval != DD_OK ) { debug_log ( "Unable to create primary surface: %s", get_ddraw_error_message ( ddrval ) ); return ( FALSE ); } #endif if ( ddraw.use_double_buffer ) { // // Get the back screen from this surface. // memset ( &caps, 0, sizeof ( caps ) ); caps.dwCaps = DDSCAPS_BACKBUFFER; #ifdef _WIN32 ddrval = IDirectDrawSurface7_GetAttachedSurface ( ddraw.lpFrontBuffer, &caps, &ddraw.lpBackBuffer ); if ( ddrval != DD_OK ) { debug_log ( "Unable to get backbuffer: %s", get_ddraw_error_message ( ddrval ) ); return ( FALSE ); } #endif } if ( ddraw.use_system_memory ) { // // Create the system memory surface // memset ( &ddsd, 0, sizeof ( ddsd ) ); ddsd.dwSize = sizeof( ddsd ); #ifdef _WIN32 ddrval = IDirectDrawSurface7_GetSurfaceDesc ( ddraw.lpFrontBuffer, &ddsd ); #endif ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE | DDSCAPS_SYSTEMMEMORY; ddsd.dwHeight = height; ddsd.dwWidth = width; #ifdef _WIN32 ddrval = IDirectDraw7_CreateSurface ( ddraw.ddraw , &ddsd, &ddraw.lpRenderBuffer, NULL ); if ( ddrval != DD_OK ) { debug_log ( "Unable to create system memory surface: %s", get_ddraw_error_message ( ddrval ) ); return ( FALSE ); } #endif } else { // // Set the render buffer // if ( ddraw.use_double_buffer ) { ddraw.lpRenderBuffer = ddraw.lpBackBuffer; ddraw.lpRenderBuffer = ddraw.lpBackBuffer; } else { ddraw.lpRenderBuffer = ddraw.lpFrontBuffer; ddraw.lpRenderBuffer = ddraw.lpFrontBuffer; } } if ( ddraw.use_z_buffer ) { // // Create the zbuffer and attach it to the render buffer. // memset ( &ddsd, 0, sizeof ( ddsd ) ); ddsd.dwSize = sizeof ( ddsd ); #ifdef _WIN32 ddrval = IDirectDrawSurface7_GetSurfaceDesc ( ddraw.lpFrontBuffer, &ddsd ); #endif ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY; ddsd.dwHeight = height; ddsd.dwWidth = width; get_ddraw_zbuffer_pixel_format ( &ddsd.ddpfPixelFormat ); #ifdef _WIN32 ddrval = IDirectDraw7_CreateSurface ( ddraw.ddraw, &ddsd, &ddraw.lpZBuffer, NULL ); if ( ddrval != DD_OK ) { debug_log ( "Unable to create Zbuffer surface: %s", get_ddraw_error_message ( ddrval ) ); return ( FALSE ); } ddrval = IDirectDrawSurface7_AddAttachedSurface ( ddraw.lpRenderBuffer, ddraw.lpZBuffer ); if ( ddrval != DD_OK ) { debug_log ( "Unable to attach Zbuffer surface: %s", get_ddraw_error_message ( ddrval ) ); return ( FALSE ); } #endif } application_video_width = width; application_video_height = height; return ( TRUE ); }
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; }