Exemple #1
0
/*****************************************************************************
 * 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;
}
Exemple #2
0
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;
}
Exemple #3
0
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 );
}
Exemple #4
0
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;
}