示例#1
0
文件: drawdd.c 项目: ef1105/mameplus
static HRESULT create_surface(dd_info *dd, DDSURFACEDESC2 *desc, IDirectDrawSurface7 **surface, const char *type)
{
	HRESULT result;

	// create the surface as requested
	result = IDirectDraw7_CreateSurface(dd->ddraw, desc, surface, NULL);
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X creating %s surface\n"), (int)result, type);
		return result;
	}

	// get a description of the primary surface
	result = IDirectDrawSurface7_GetSurfaceDesc(*surface, desc);
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X getting %s surface desciption\n"), (int)result, type);
		IDirectDrawSurface7_Release(*surface);
		*surface = NULL;
		return result;
	}

	// print out the good stuff
	osd_printf_verbose(_WINDOWS("DirectDraw: %s surface created: %dx%dx%d (R=%08X G=%08X B=%08X)\n"),
				type,
				(int)desc->dwWidth,
				(int)desc->dwHeight,
				(int)desc->ddpfPixelFormat.dwRGBBitCount,
				(UINT32)desc->ddpfPixelFormat.dwRBitMask,
				(UINT32)desc->ddpfPixelFormat.dwGBitMask,
				(UINT32)desc->ddpfPixelFormat.dwBBitMask);
	return result;
}
示例#2
0
文件: drawdd.c 项目: ef1105/mameplus
static int create_clipper(win_window_info *window)
{
	dd_info *dd = (dd_info *)window->drawdata;
	HRESULT result;

	// create a clipper for the primary surface
	result = IDirectDraw7_CreateClipper(dd->ddraw, 0, &dd->clipper, NULL);
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X creating clipper\n"), (int)result);
		return 1;
	}

	// set the clipper's hwnd
	result = IDirectDrawClipper_SetHWnd(dd->clipper, 0, window->hwnd);
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X setting clipper hwnd\n"), (int)result);
		return 1;
	}

	// set the clipper on the primary surface
	result = IDirectDrawSurface7_SetClipper(dd->primary, dd->clipper);
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X setting clipper on primary surface\n"), (int)result);
		return 1;
	}
	return 0;
}
示例#3
0
文件: drawdd.c 项目: ef1105/mameplus
static void pick_best_mode(win_window_info *window)
{
	dd_info *dd = (dd_info *)window->drawdata;
	mode_enum_info einfo;
	HRESULT result;

	// determine the minimum width/height for the selected target
	// note: technically we should not be calling this from an alternate window
	// thread; however, it is only done during init time, and the init code on
	// the main thread is waiting for us to finish, so it is safe to do so here
	window->target->compute_minimum_size(einfo.minimum_width, einfo.minimum_height);

	// use those as the target for now
	einfo.target_width = einfo.minimum_width * MAX(1, video_config.prescale);
	einfo.target_height = einfo.minimum_height * MAX(1, video_config.prescale);

	// determine the refresh rate of the primary screen
	einfo.target_refresh = 60.0;
	const screen_device *primary_screen = window->machine().config().first_screen();
	if (primary_screen != NULL)
		einfo.target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds());
	printf("Target refresh = %f\n", einfo.target_refresh);

	// if we're not stretching, allow some slop on the minimum since we can handle it
	if (!video_config.hwstretch)
	{
		einfo.minimum_width -= 4;
		einfo.minimum_height -= 4;
	}

	// if we are stretching, aim for a mode approximately 2x the game's resolution
	else if (video_config.prescale <= 1)
	{
		einfo.target_width *= 2;
		einfo.target_height *= 2;
	}

	// fill in the rest of the data
	einfo.window = window;
	einfo.best_score = 0.0f;

	// enumerate the modes
	osd_printf_verbose(_WINDOWS("DirectDraw: Selecting video mode...\n"));
	result = IDirectDraw7_EnumDisplayModes(dd->ddraw, DDEDM_REFRESHRATES, NULL, &einfo, enum_modes_callback);
	if (result != DD_OK) osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X during EnumDisplayModes call\n"), (int)result);
	osd_printf_verbose(_WINDOWS("DirectDraw: Mode selected = %4dx%4d@%3dHz\n"), dd->width, dd->height, dd->refresh);
}
示例#4
0
d3d *drawd3d8_init(void)
{
	direct3dcreate8_ptr direct3dcreate8;
	HINSTANCE dllhandle;
	IDirect3D8 *d3d8;
	d3d *d3dptr;

	// dynamically grab the create function from d3d8.dll
	dllhandle = LoadLibrary(TEXT("d3d8.dll"));
	if (dllhandle == NULL)
	{
		mame_printf_verbose(_WINDOWS("Direct3D: Unable to access d3d8.dll\n"));
		return NULL;
	}

	// import the create function
	direct3dcreate8 = (direct3dcreate8_ptr)GetProcAddress(dllhandle, "Direct3DCreate8");
	if (direct3dcreate8 == NULL)
	{
		mame_printf_verbose(_WINDOWS("Direct3D: Unable to find Direct3DCreate8\n"));
		FreeLibrary(dllhandle);
		dllhandle = NULL;
		return NULL;
	}

	// create our core direct 3d object
	d3d8 = (*direct3dcreate8)(D3D_SDK_VERSION);
	if (d3d8 == NULL)
	{
		mame_printf_verbose(_WINDOWS("Direct3D: Error attempting to initialize Direct3D8\n"));
		FreeLibrary(dllhandle);
		dllhandle = NULL;
		return NULL;
	}

	// allocate an object to hold our data
	d3dptr = global_alloc(d3d);
	d3dptr->version = 8;
	d3dptr->d3dobj = d3d8;
	d3dptr->dllhandle = dllhandle;
	set_interfaces(d3dptr);

	mame_printf_verbose(_WINDOWS("Direct3D: Using Direct3D 8\n"));
	return d3dptr;
}
示例#5
0
文件: drawdd.c 项目: ef1105/mameplus
int drawdd_init(running_machine &machine, win_draw_callbacks *callbacks)
{
	// dynamically grab the create function from ddraw.dll
	dllhandle = LoadLibrary(TEXT("ddraw.dll"));
	if (dllhandle == NULL)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Unable to access ddraw.dll\n"));
		return 1;
	}

	// import the create function
	directdrawcreateex = (directdrawcreateex_ptr)GetProcAddress(dllhandle, "DirectDrawCreateEx");
	if (directdrawcreateex == NULL)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Unable to find DirectDrawCreateEx\n"));
		FreeLibrary(dllhandle);
		dllhandle = NULL;
		return 1;
	}

	// import the enumerate function
	directdrawenumerateex = (directdrawenumerateex_ptr)GetProcAddress(dllhandle, "DirectDrawEnumerateExA");
	if (directdrawenumerateex == NULL)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Unable to find DirectDrawEnumerateExA\n"));
		FreeLibrary(dllhandle);
		dllhandle = NULL;
		return 1;
	}

	// fill in the callbacks
	memset(callbacks, 0, sizeof(*callbacks));
	callbacks->exit = drawdd_exit;
	callbacks->window_init = drawdd_window_init;
	callbacks->window_get_primitives = drawdd_window_get_primitives;
	callbacks->window_draw = drawdd_window_draw;
	callbacks->window_destroy = drawdd_window_destroy;

	osd_printf_verbose(_WINDOWS("DirectDraw: Using DirectDraw 7\n"));
	return 0;
}
示例#6
0
static void sound_exit(running_machine &machine)
{
	// kill the buffers and dsound
	dsound_destroy_buffers();
	dsound_kill();

	// print out over/underflow stats
	if (buffer_overflows || buffer_underflows)
		mame_printf_verbose(_WINDOWS("Sound: buffer overflows=%d underflows=%d\n"), buffer_overflows, buffer_underflows);

	LOG(("Sound buffer: overflows=%d underflows=%d\n", buffer_overflows, buffer_underflows));
}
示例#7
0
文件: drawdd.c 项目: ef1105/mameplus
static int ddraw_create(win_window_info *window)
{
	dd_info *dd = (dd_info *)window->drawdata;
	HRESULT result;
	int verify;

	// if a device exists, free it
	if (dd->ddraw != NULL)
		ddraw_delete(window);

	// create the DirectDraw object
	result = (*directdrawcreateex)(dd->adapter_ptr, (LPVOID *)&dd->ddraw, WRAP_REFIID(IID_IDirectDraw7), NULL);
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X during DirectDrawCreateEx call\n"), (int)result);
		goto error;
	}

	// verify the caps
	verify = ddraw_verify_caps(dd);
	if (verify == 2)
	{
		osd_printf_error(_WINDOWS("DirectDraw: Error - Device does not meet minimum requirements for DirectDraw rendering\n"));
		goto error;
	}
	if (verify == 1)
		osd_printf_verbose(_WINDOWS("DirectDraw: Warning - Device may not perform well for DirectDraw rendering\n"));

	// set the cooperative level
	// for non-window modes, we will use full screen here
	result = IDirectDraw7_SetCooperativeLevel(dd->ddraw, win_window_list->hwnd, DDSCL_SETFOCUSWINDOW);
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X during IDirectDraw7_SetCooperativeLevel(FOCUSWINDOW) call\n"), (int)result);
		goto error;
	}
	result = IDirectDraw7_SetCooperativeLevel(dd->ddraw, window->hwnd, DDSCL_SETDEVICEWINDOW | (window->fullscreen ? DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE : DDSCL_NORMAL));
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X during IDirectDraw7_SetCooperativeLevel(DEVICEWINDOW) call\n"), (int)result);
		goto error;
	}

	// full screen mode: set the resolution
	if (window->fullscreen && video_config.switchres)
	{
		result = IDirectDraw7_SetDisplayMode(dd->ddraw, dd->width, dd->height, 32, dd->refresh, 0);
		if (result != DD_OK)
		{
			osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X attempting to set video mode %dx%d@%d call\n"), (int)result, dd->width, dd->height, dd->refresh);
			goto error;
		}
	}

	return ddraw_create_surfaces(window);

error:
	ddraw_delete(window);
	return 1;
}
示例#8
0
文件: drawdd.c 项目: ef1105/mameplus
static int ddraw_verify_caps(dd_info *dd)
{
	int retval = 0;
	HRESULT result;

	// get the capabilities
	dd->ddcaps.dwSize = sizeof(dd->ddcaps);
	dd->helcaps.dwSize = sizeof(dd->helcaps);
	result = IDirectDraw7_GetCaps(dd->ddraw, &dd->ddcaps, &dd->helcaps);
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X during IDirectDraw7_GetCaps call\n"), (int)result);
		return 1;
	}

	// determine if hardware stretching is available
	if ((dd->ddcaps.dwCaps & DDCAPS_BLTSTRETCH) == 0)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Warning - Device does not support hardware stretching\n"));
		retval = 1;
	}

	return retval;
}
示例#9
0
文件: drawdd.c 项目: ef1105/mameplus
static void get_adapter_for_monitor(dd_info *dd, win_monitor_info *monitor)
{
	monitor_enum_info einfo;
	HRESULT result;

	// try to find our monitor
	memset(&einfo, 0, sizeof(einfo));
	einfo.monitor = monitor;
	result = (*directdrawenumerateex)(monitor_enum_callback, &einfo, DDENUM_ATTACHEDSECONDARYDEVICES);
	if (result != DD_OK) osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X during DirectDrawEnumerateEx call\n"), (int)result);

	// set up the adapter
	if (einfo.foundit && einfo.guid_ptr != NULL)
	{
		dd->adapter = einfo.guid;
		dd->adapter_ptr = &dd->adapter;
	}
	else
		dd->adapter_ptr = NULL;
}
示例#10
0
文件: drawdd.c 项目: ef1105/mameplus
static int drawdd_window_init(win_window_info *window)
{
	dd_info *dd;

	// allocate memory for our structures
	dd = global_alloc_clear(dd_info);
	window->drawdata = dd;

	// configure the adapter for the mode we want
	if (config_adapter_mode(window))
		goto error;

	// create the ddraw object
	if (ddraw_create(window))
		goto error;

	return 0;

error:
	drawdd_window_destroy(window);
	osd_printf_error(_WINDOWS("Unable to initialize DirectDraw.\n"));
	return 1;
}
示例#11
0
文件: drawdd.c 项目: ef1105/mameplus
static void blit_to_primary(win_window_info *window, int srcwidth, int srcheight)
{
	dd_info *dd = (dd_info *)window->drawdata;
	IDirectDrawSurface7 *target = (dd->back != NULL) ? dd->back : dd->primary;
	win_monitor_info *monitor = winwindow_video_window_monitor(window, NULL);
	DDBLTFX blitfx = { sizeof(DDBLTFX) };
	RECT clear, outer, dest, source;
	INT32 dstwidth, dstheight;
	HRESULT result;

	// compute source rect
	source.left = source.top = 0;
	source.right = srcwidth;
	source.bottom = srcheight;

	// compute outer rect -- windowed version
	if (!window->fullscreen)
	{
		GetClientRect(window->hwnd, &outer);
		ClientToScreen(window->hwnd, &((LPPOINT)&outer)[0]);
		ClientToScreen(window->hwnd, &((LPPOINT)&outer)[1]);

		// adjust to be relative to the monitor
		outer.left -= monitor->info.rcMonitor.left;
		outer.right -= monitor->info.rcMonitor.left;
		outer.top -= monitor->info.rcMonitor.top;
		outer.bottom -= monitor->info.rcMonitor.top;
	}

	// compute outer rect -- full screen version
	else
	{
		calc_fullscreen_margins(window, dd->primarydesc.dwWidth, dd->primarydesc.dwHeight, &outer);
	}

	// if we're respecting the aspect ratio, we need to adjust to fit
	dstwidth = rect_width(&outer);
	dstheight = rect_height(&outer);
	if (!video_config.hwstretch)
	{
		// trim the source if necessary
		if (rect_width(&outer) < srcwidth)
		{
			source.left += (srcwidth - rect_width(&outer)) / 2;
			source.right = source.left + rect_width(&outer);
		}
		if (rect_height(&outer) < srcheight)
		{
			source.top += (srcheight - rect_height(&outer)) / 2;
			source.bottom = source.top + rect_height(&outer);
		}

		// match the destination and source sizes
		dstwidth = srcwidth = source.right - source.left;
		dstheight = srcheight = source.bottom - source.top;
	}
	else if (video_config.keepaspect)
	{
		// compute the appropriate visible area
		window->target->compute_visible_area(rect_width(&outer), rect_height(&outer), winvideo_monitor_get_aspect(monitor), window->target->orientation(), dstwidth, dstheight);
	}

	// center within
	dest.left = outer.left + (rect_width(&outer) - dstwidth) / 2;
	dest.right = dest.left + dstwidth;
	dest.top = outer.top + (rect_height(&outer) - dstheight) / 2;
	dest.bottom = dest.top + dstheight;

	// compare against last destination; if different, force a redraw
	if (dest.left != dd->lastdest.left || dest.right != dd->lastdest.right || dest.top != dd->lastdest.top || dest.bottom != dd->lastdest.bottom)
	{
		dd->lastdest = dest;
		update_outer_rects(dd);
	}

	// clear outer rects if we need to
	if (dd->clearouter != 0)
	{
		dd->clearouter--;

		// clear the left edge
		if (dest.left > outer.left)
		{
			clear = outer;
			clear.right = dest.left;
			result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
			if (result != DD_OK) osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X clearing the screen\n"), (int)result);
		}

		// clear the right edge
		if (dest.right < outer.right)
		{
			clear = outer;
			clear.left = dest.right;
			result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
			if (result != DD_OK) osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X clearing the screen\n"), (int)result);
		}

		// clear the top edge
		if (dest.top > outer.top)
		{
			clear = outer;
			clear.bottom = dest.top;
			result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
			if (result != DD_OK) osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X clearing the screen\n"), (int)result);
		}

		// clear the bottom edge
		if (dest.bottom < outer.bottom)
		{
			clear = outer;
			clear.top = dest.bottom;
			result = IDirectDrawSurface_Blt(target, &clear, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &blitfx);
			if (result != DD_OK) osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X clearing the screen\n"), (int)result);
		}
	}

	// do the blit
	result = IDirectDrawSurface7_Blt(target, &dest, dd->blit, &source, DDBLT_WAIT, NULL);
	if (result != DD_OK) osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X blitting to the screen\n"), (int)result);

	// page flip if triple buffered
	if (window->fullscreen && dd->back != NULL)
	{
		result = IDirectDrawSurface7_Flip(dd->primary, NULL, DDFLIP_WAIT);
		if (result != DD_OK) osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X waiting for VBLANK\n"), (int)result);
	}
}
示例#12
0
static HRESULT dsound_create_buffers(void)
{
	HRESULT result;
	void *buffer;
	DWORD locked;

	// create a buffer desc for the primary buffer
	memset(&primary_desc, 0, sizeof(primary_desc));
	primary_desc.dwSize	= sizeof(primary_desc);
	primary_desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2;
	primary_desc.lpwfxFormat = NULL;

	// create the primary buffer
	result = IDirectSound_CreateSoundBuffer(dsound, &primary_desc, &primary_buffer, NULL);
	if (result != DS_OK)
	{
		mame_printf_error(_WINDOWS("Error creating primary DirectSound buffer: %08x\n"), (UINT32)result);
		goto error;
	}

	// attempt to set the primary format
	result = IDirectSoundBuffer_SetFormat(primary_buffer, &stream_format);
	if (result != DS_OK)
	{
		mame_printf_error(_WINDOWS("Error setting primary DirectSound buffer format: %08x\n"), (UINT32)result);
		goto error;
	}

	// get the primary format
	result = IDirectSoundBuffer_GetFormat(primary_buffer, &primary_format, sizeof(primary_format), NULL);
	if (result != DS_OK)
	{
		mame_printf_error(_WINDOWS("Error getting primary DirectSound buffer format: %08x\n"), (UINT32)result);
		goto error;
	}
	mame_printf_verbose(_WINDOWS("DirectSound: Primary buffer: %d Hz, %d bits, %d channels\n"),
				(int)primary_format.nSamplesPerSec, (int)primary_format.wBitsPerSample, (int)primary_format.nChannels);

	// create a buffer desc for the stream buffer
	memset(&stream_desc, 0, sizeof(stream_desc));
	stream_desc.dwSize = sizeof(stream_desc);
	stream_desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLFREQUENCY;
	stream_desc.dwBufferBytes = stream_buffer_size;
	stream_desc.lpwfxFormat	= &stream_format;

	// create the stream buffer
	result = IDirectSound_CreateSoundBuffer(dsound, &stream_desc, &stream_buffer, NULL);
	if (result != DS_OK)
	{
		mame_printf_error(_WINDOWS("Error creating DirectSound stream buffer: %08x\n"), (UINT32)result);
		goto error;
	}

	// lock the buffer
	result = IDirectSoundBuffer_Lock(stream_buffer, 0, stream_buffer_size, &buffer, &locked, NULL, NULL, 0);
	if (result != DS_OK)
	{
		mame_printf_error(_WINDOWS("Error locking DirectSound stream buffer: %08x\n"), (UINT32)result);
		goto error;
	}

	// clear the buffer and unlock it
	memset(buffer, 0, locked);
	IDirectSoundBuffer_Unlock(stream_buffer, buffer, locked, NULL, 0);
	return DS_OK;

	// error handling
error:
	dsound_destroy_buffers();
	return result;
}
示例#13
0
文件: drawdd.c 项目: ef1105/mameplus
static void compute_blit_surface_size(win_window_info *window)
{
	dd_info *dd = (dd_info *)window->drawdata;
	INT32 newwidth, newheight;
	int xscale, yscale;
	RECT client;

	// start with the minimum size
	window->target->compute_minimum_size(newwidth, newheight);

	// get the window's client rectangle
	GetClientRect(window->hwnd, &client);

	// hardware stretch case: apply prescale
	if (video_config.hwstretch)
	{
		int prescale = (video_config.prescale < 1) ? 1 : video_config.prescale;

		// clamp the prescale to something smaller than the target bounds
		xscale = prescale;
		while (xscale > 1 && newwidth * xscale > rect_width(&client))
			xscale--;
		yscale = prescale;
		while (yscale > 1 && newheight * yscale > rect_height(&client))
			yscale--;
	}

	// non stretch case
	else
	{
		INT32 target_width = rect_width(&client);
		INT32 target_height = rect_height(&client);
		float desired_aspect = 1.0f;

		// compute the appropriate visible area if we're trying to keepaspect
		if (video_config.keepaspect)
		{
			win_monitor_info *monitor = winwindow_video_window_monitor(window, NULL);
			window->target->compute_visible_area(target_width, target_height, winvideo_monitor_get_aspect(monitor), window->target->orientation(), target_width, target_height);
			desired_aspect = (float)target_width / (float)target_height;
		}

		// compute maximum integral scaling to fit the window
		xscale = (target_width + 2) / newwidth;
		yscale = (target_height + 2) / newheight;

		// try a little harder to keep the aspect ratio if desired
		if (video_config.keepaspect)
		{
			// if we could stretch more in the X direction, and that makes a better fit, bump the xscale
			while (newwidth * (xscale + 1) <= rect_width(&client) &&
				better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale + 1), newheight * yscale, desired_aspect))
				xscale++;

			// if we could stretch more in the Y direction, and that makes a better fit, bump the yscale
			while (newheight * (yscale + 1) <= rect_height(&client) &&
				better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale + 1), desired_aspect))
				yscale++;

			// now that we've maxed out, see if backing off the maximally stretched one makes a better fit
			if (rect_width(&client) - newwidth * xscale < rect_height(&client) - newheight * yscale)
			{
				while (xscale > 1 && better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale - 1), newheight * yscale, desired_aspect))
					xscale--;
			}
			else
			{
				while (yscale > 1 && better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale - 1), desired_aspect))
					yscale--;
			}
		}
	}

	// ensure at least a scale factor of 1
	if (xscale == 0) xscale = 1;
	if (yscale == 0) yscale = 1;

	// apply the final scale
	newwidth *= xscale;
	newheight *= yscale;
	if (newwidth != dd->blitwidth || newheight != dd->blitheight)
	{
		// force some updates
		update_outer_rects(dd);
		osd_printf_verbose(_WINDOWS("DirectDraw: New blit size = %dx%d\n"), newwidth, newheight);
	}
	dd->blitwidth = newwidth;
	dd->blitheight = newheight;
}
示例#14
0
d3d *drawd3d9_init(void)
{
	direct3dcreate9_ptr direct3dcreate9;
	HINSTANCE dllhandle;
	IDirect3D9 *d3d9;
	d3d *d3dptr;
	bool post_available = true;

	// dynamically grab the create function from d3d9.dll
	dllhandle = LoadLibrary(TEXT("d3d9.dll"));
	if (dllhandle == NULL)
	{
		mame_printf_verbose(_WINDOWS("Direct3D: Unable to access d3d9.dll\n"));
		return NULL;
	}

	// import the create function
	direct3dcreate9 = (direct3dcreate9_ptr)GetProcAddress(dllhandle, "Direct3DCreate9");
	if (direct3dcreate9 == NULL)
	{
		mame_printf_verbose(_WINDOWS("Direct3D: Unable to find Direct3DCreate9\n"));
		FreeLibrary(dllhandle);
		dllhandle = NULL;
		return NULL;
	}

	// create our core direct 3d object
	d3d9 = (*direct3dcreate9)(D3D_SDK_VERSION);
	if (d3d9 == NULL)
	{
		mame_printf_verbose(_WINDOWS("Direct3D: Error attempting to initialize Direct3D9\n"));
		FreeLibrary(dllhandle);
		dllhandle = NULL;
		return NULL;
	}

	// dynamically grab the shader load function from d3dx9.dll
	HINSTANCE fxhandle = LoadLibrary(TEXT("d3dx9_43.dll"));
	if (fxhandle == NULL)
	{
		post_available = false;
		mame_printf_verbose(_WINDOWS("Direct3D: Warning - Unable to access d3dx9_43.dll; disabling post-effect rendering\n"));
	}

	// import the create function
	if(post_available)
	{
		g_load_effect = (direct3dx9_loadeffect_ptr)GetProcAddress(fxhandle, "D3DXCreateEffectFromFileW");
		if (g_load_effect == NULL)
		{
			printf("Direct3D: Unable to find D3DXCreateEffectFromFileW\n");
			FreeLibrary(dllhandle);
			fxhandle = NULL;
			dllhandle = NULL;
			return NULL;
		}
	}
	else
	{
		g_load_effect = NULL;
		post_available = false;
		mame_printf_verbose(_WINDOWS("Direct3D: Warning - Unable to get a handle to D3DXCreateEffectFromFileW; disabling post-effect rendering\n"));
	}

	// allocate an object to hold our data
	d3dptr = global_alloc(d3d);
	d3dptr->version = 9;
	d3dptr->d3dobj = d3d9;
	d3dptr->dllhandle = dllhandle;
	d3dptr->post_fx_available = post_available;
	set_interfaces(d3dptr);

	mame_printf_verbose(_WINDOWS("Direct3D: Using Direct3D 9\n"));
	return d3dptr;
}
示例#15
0
文件: drawdd.c 项目: ef1105/mameplus
static int config_adapter_mode(win_window_info *window)
{
	DDDEVICEIDENTIFIER2 identifier;
	dd_info *dd = (dd_info *)window->drawdata;
	HRESULT result;

	// choose the monitor number
	get_adapter_for_monitor(dd, window->monitor);

	// create a temporary DirectDraw object
	result = (*directdrawcreateex)(dd->adapter_ptr, (LPVOID *)&dd->ddraw, WRAP_REFIID(IID_IDirectDraw7), NULL);
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X during DirectDrawCreateEx call\n"), (int)result);
		return 1;
	}

	// get the identifier
	result = IDirectDraw7_GetDeviceIdentifier(dd->ddraw, &identifier, 0);
	if (result != DD_OK)
	{
		osd_printf_error(_WINDOWS("Error getting identifier for device\n"));
		return 1;
	}
	osd_printf_verbose(_WINDOWS("DirectDraw: Configuring device %s\n"), identifier.szDescription);

	// get the current display mode
	memset(&dd->origmode, 0, sizeof(dd->origmode));
	dd->origmode.dwSize = sizeof(dd->origmode);
	result = IDirectDraw7_GetDisplayMode(dd->ddraw, &dd->origmode);
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X getting current display mode\n"), (int)result);
		IDirectDraw7_Release(dd->ddraw);
		return 1;
	}

	// choose a resolution: full screen mode case
	if (window->fullscreen)
	{
		// default to the current mode exactly
		dd->width = dd->origmode.dwWidth;
		dd->height = dd->origmode.dwHeight;
		dd->refresh = dd->origmode.dwRefreshRate;

		// if we're allowed to switch resolutions, override with something better
		if (video_config.switchres)
			pick_best_mode(window);
	}

	// release the DirectDraw object
	IDirectDraw7_Release(dd->ddraw);
	dd->ddraw = NULL;

	// if we're not changing resolutions, make sure we have a resolution we can handle
	if (!window->fullscreen || !video_config.switchres)
	{
		switch (dd->origmode.ddpfPixelFormat.dwRBitMask)
		{
			case 0x00ff0000:
			case 0x000000ff:
			case 0xf800:
			case 0x7c00:
				break;

			default:
				osd_printf_verbose(_WINDOWS("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n"), (int)dd->origmode.ddpfPixelFormat.dwRBitMask, (int)dd->origmode.ddpfPixelFormat.dwGBitMask, (int)dd->origmode.ddpfPixelFormat.dwBBitMask);
				return 1;
		}
	}

	return 0;
}
示例#16
0
文件: drawdd.c 项目: ef1105/mameplus
static int ddraw_create_surfaces(win_window_info *window)
{
	dd_info *dd = (dd_info *)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)
		{
			osd_printf_verbose(_WINDOWS("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;
		global_free_array(dd->membuffer);
		dd->membuffer = global_alloc_array(UINT8, dd->membuffersize);
	}
	if (dd->membuffer == NULL)
		goto error;

	// create a clipper for windowed mode
	if (!window->fullscreen && create_clipper(window))
		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 gamma = options.full_screen_gamma();
		if (brightness != 1.0f || contrast != 1.0f || gamma != 1.0f)
		{
			// see if we can get a GammaControl object
			result = IDirectDrawSurface_QueryInterface(dd->primary, WRAP_REFIID(IID_IDirectDrawGammaControl), (void **)&dd->gamma);
			if (result != DD_OK)
			{
				osd_printf_warning(_WINDOWS("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)
					osd_printf_verbose(_WINDOWS("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;
}
示例#17
0
static HRESULT dsound_init(running_machine &machine)
{
	HRESULT result;

	// create the DirectSound object
	result = DirectSoundCreate(NULL, &dsound, NULL);
	if (result != DS_OK)
	{
		mame_printf_error(_WINDOWS("Error creating DirectSound: %08x\n"), (UINT32)result);
		goto error;
	}

	// get the capabilities
	dsound_caps.dwSize = sizeof(dsound_caps);
	result = IDirectSound_GetCaps(dsound, &dsound_caps);
	if (result != DS_OK)
	{
		mame_printf_error(_WINDOWS("Error getting DirectSound capabilities: %08x\n"), (UINT32)result);
		goto error;
	}

	// set the cooperative level
	result = IDirectSound_SetCooperativeLevel(dsound, win_window_list->hwnd, DSSCL_PRIORITY);
	if (result != DS_OK)
	{
		mame_printf_error(_WINDOWS("Error setting DirectSound cooperative level: %08x\n"), (UINT32)result);
		goto error;
	}

	// make a format description for what we want
	stream_format.wBitsPerSample	= 16;
	stream_format.wFormatTag		= WAVE_FORMAT_PCM;
	stream_format.nChannels			= 2;
	stream_format.nSamplesPerSec	= machine.sample_rate();
	stream_format.nBlockAlign		= stream_format.wBitsPerSample * stream_format.nChannels / 8;
	stream_format.nAvgBytesPerSec	= stream_format.nSamplesPerSec * stream_format.nBlockAlign;

	// compute the buffer size based on the output sample rate
	stream_buffer_size = stream_format.nSamplesPerSec * stream_format.nBlockAlign * downcast<windows_options &>(machine.options()).audio_latency() / 10;
	stream_buffer_size = (stream_buffer_size / 1024) * 1024;
	if (stream_buffer_size < 1024)
		stream_buffer_size = 1024;

	LOG(("stream_buffer_size = %d\n", stream_buffer_size));

	// create the buffers
	result = dsound_create_buffers();
	if (result != DS_OK)
		goto error;

	// start playing
	result = IDirectSoundBuffer_Play(stream_buffer, 0, 0, DSBPLAY_LOOPING);
	if (result != DS_OK)
	{
		mame_printf_error(_WINDOWS("Error playing: %08x\n"), (UINT32)result);
		goto error;
	}
	return DS_OK;

	// error handling
error:
	dsound_destroy_buffers();
	dsound_kill();
	return result;
}
示例#18
0
文件: drawdd.c 项目: ef1105/mameplus
static int drawdd_window_draw(win_window_info *window, HDC dc, int update)
{
	dd_info *dd = (dd_info *)window->drawdata;
	render_primitive *prim;
	int usemembuffer = FALSE;
	HRESULT result;

	// if we haven't been created, just punt
	if (dd == NULL)
		return 1;

	// if we're updating, remember to erase the outer stuff
	if (update)
		update_outer_rects(dd);

	// if we have a ddraw object, check the cooperative level
	if (ddraw_test_cooperative(window))
		return 1;

	// get the size; if we're too small, delete the existing surfaces
	if (dd->blitwidth > dd->blitdesc.dwWidth || dd->blitheight > dd->blitdesc.dwHeight)
		ddraw_delete_surfaces(window);

	// if we need to create surfaces, do it now
	if (dd->blit == NULL && ddraw_create_surfaces(window) != 0)
		return 1;

	// select our surface and lock it
	result = IDirectDrawSurface7_Lock(dd->blit, NULL, &dd->blitdesc, DDLOCK_WAIT, NULL);
	if (result == DDERR_SURFACELOST)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Lost surfaces; deleting and retrying next frame\n"));
		ddraw_delete_surfaces(window);
		return 1;
	}
	if (result != DD_OK)
	{
		osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X locking blit surface\n"), (int)result);
		return 1;
	}

	// render to it
	window->primlist->acquire_lock();

	// scan the list of primitives for tricky stuff
	for (prim = window->primlist->first(); prim != NULL; prim = prim->next())
		if (PRIMFLAG_GET_BLENDMODE(prim->flags) != BLENDMODE_NONE ||
			(prim->texture.base != NULL && PRIMFLAG_GET_TEXFORMAT(prim->flags) == TEXFORMAT_ARGB32))
		{
			usemembuffer = TRUE;
			break;
		}

	// if we're using the memory buffer, draw offscreen first and then copy
	if (usemembuffer)
	{
		int x, y;

		// based on the target format, use one of our standard renderers
		switch (dd->blitdesc.ddpfPixelFormat.dwRBitMask)
		{
			case 0x00ff0000:    software_renderer<UINT32, 0,0,0, 16,8,0>::draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth);  break;
			case 0x000000ff:    software_renderer<UINT32, 0,0,0, 0,8,16>::draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth);  break;
			case 0xf800:        software_renderer<UINT16, 3,2,3, 11,5,0>::draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth);  break;
			case 0x7c00:        software_renderer<UINT16, 3,3,3, 10,5,0>::draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth);  break;
			default:
				osd_printf_verbose(_WINDOWS("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n"), (int)dd->blitdesc.ddpfPixelFormat.dwRBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwGBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwBBitMask);
				break;
		}

		// handle copying to both 16bpp and 32bpp destinations
		for (y = 0; y < dd->blitheight; y++)
		{
			if (dd->blitdesc.ddpfPixelFormat.dwRGBBitCount == 32)
			{
				UINT32 *src = (UINT32 *)dd->membuffer + y * dd->blitwidth;
				UINT32 *dst = (UINT32 *)((UINT8 *)dd->blitdesc.lpSurface + y * dd->blitdesc.lPitch);
				for (x = 0; x < dd->blitwidth; x++)
					*dst++ = *src++;
			}
			else if (dd->blitdesc.ddpfPixelFormat.dwRGBBitCount == 16)
			{
				UINT16 *src = (UINT16 *)dd->membuffer + y * dd->blitwidth;
				UINT16 *dst = (UINT16 *)((UINT8 *)dd->blitdesc.lpSurface + y * dd->blitdesc.lPitch);
				for (x = 0; x < dd->blitwidth; x++)
					*dst++ = *src++;
			}
		}

	}

	// otherwise, draw directly
	else
	{
		// based on the target format, use one of our standard renderers
		switch (dd->blitdesc.ddpfPixelFormat.dwRBitMask)
		{
			case 0x00ff0000:    software_renderer<UINT32, 0,0,0, 16,8,0, true>::draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break;
			case 0x000000ff:    software_renderer<UINT32, 0,0,0, 0,8,16, true>::draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break;
			case 0xf800:        software_renderer<UINT16, 3,2,3, 11,5,0, true>::draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break;
			case 0x7c00:        software_renderer<UINT16, 3,3,3, 10,5,0, true>::draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break;
			default:
				osd_printf_verbose(_WINDOWS("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n"), (int)dd->blitdesc.ddpfPixelFormat.dwRBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwGBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwBBitMask);
				break;
		}
	}
	window->primlist->release_lock();

	// unlock and blit
	result = IDirectDrawSurface7_Unlock(dd->blit, NULL);
	if (result != DD_OK) osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X unlocking blit surface\n"), (int)result);

	// sync to VBLANK
	if ((video_config.waitvsync || video_config.syncrefresh) && window->machine().video().throttled() && (!window->fullscreen || dd->back == NULL))
	{
		result = IDirectDraw7_WaitForVerticalBlank(dd->ddraw, DDWAITVB_BLOCKBEGIN, NULL);
		if (result != DD_OK) osd_printf_verbose(_WINDOWS("DirectDraw: Error %08X waiting for VBLANK\n"), (int)result);
	}

	// complete the blitting
	blit_to_primary(window, dd->blitwidth, dd->blitheight);
	return 0;
}