Beispiel #1
0
int winwindow_video_window_create(int index, win_monitor_info *monitor, const win_window_config *config)
{
	win_window_info *window, *win;
	char option[20];

	assert(GetCurrentThreadId() == main_threadid);

	// allocate a new window object
	window = malloc_or_die(sizeof(*window));
	memset(window, 0, sizeof(*window));
	window->maxwidth = config->width;
	window->maxheight = config->height;
	window->refresh = config->refresh;
	window->monitor = monitor;
	window->fullscreen = !video_config.windowed;

	// see if we are safe for fullscreen
	window->fullscreen_safe = TRUE;
	for (win = win_window_list; win != NULL; win = win->next)
		if (win->monitor == monitor)
			window->fullscreen_safe = FALSE;

	// add us to the list
	*last_window_ptr = window;
	last_window_ptr = &window->next;

	// create a lock that we can use to skip blitting
	window->render_lock = osd_lock_alloc();

	// load the layout
	window->target = render_target_alloc(NULL, 0);
	if (window->target == NULL)
		goto error;
	render_target_set_orientation(window->target, video_orientation);
	render_target_set_layer_config(window->target, video_config.layerconfig);

	// set the specific view
	sprintf(option, "view%d", index);
	set_starting_view(index, window, options_get_string(option));

	// remember the current values in case they change
	window->targetview = render_target_get_view(window->target);
	window->targetorient = render_target_get_orientation(window->target);
	window->targetlayerconfig = render_target_get_layer_config(window->target);

	// make the window title
	if (video_config.numscreens == 1)
		sprintf(window->title, APPNAME ": %s [%s]", Machine->gamedrv->description, Machine->gamedrv->name);
	else
		sprintf(window->title, APPNAME ": %s [%s] - Screen %d", Machine->gamedrv->description, Machine->gamedrv->name, index);

	// set the initial maximized state
	window->startmaximized = options_get_bool("maximize");

	// finish the window creation on the window thread
	if (multithreading_enabled)
	{
		// wait until the window thread is ready to respond to events
		WaitForSingleObject(window_thread_ready_event, INFINITE);

		PostThreadMessage(window_threadid, WM_USER_FINISH_CREATE_WINDOW, 0, (LPARAM)window);
		while (window->init_state == 0)
			Sleep(1);
	}
	else
		window->init_state = complete_create(window) ? -1 : 1;

	// handle error conditions
	if (window->init_state == -1)
		goto error;
	return 0;

error:
	winwindow_video_window_destroy(window);
	return 1;
}
Beispiel #2
0
void winwindow_video_window_update(win_window_info *window)
{
	int targetview, targetorient, targetlayerconfig;

	assert(GetCurrentThreadId() == main_threadid);

	mtlog_add("winwindow_video_window_update: begin");

	// see if the target has changed significantly in window mode
	targetview = render_target_get_view(window->target);
	targetorient = render_target_get_orientation(window->target);
	targetlayerconfig = render_target_get_layer_config(window->target);
	if (targetview != window->targetview || targetorient != window->targetorient || targetlayerconfig != window->targetlayerconfig)
	{
		window->targetview = targetview;
		window->targetorient = targetorient;
		window->targetlayerconfig = targetlayerconfig;

		// in window mode, reminimize/maximize
		if (!window->fullscreen)
		{
			if (window->isminimized)
				SendMessage(window->hwnd, WM_USER_SET_MINSIZE, 0, 0);
			if (window->ismaximized)
				SendMessage(window->hwnd, WM_USER_SET_MAXSIZE, 0, 0);
		}
	}

	// if we're visible and running and not in the middle of a resize, draw
	if (window->hwnd != NULL && window->target != NULL)
	{
		int got_lock = TRUE;

		mtlog_add("winwindow_video_window_update: try lock");

		// only block if we're throttled
		if (video_config.throttle || timeGetTime() - last_update_time > 250)
			osd_lock_acquire(window->render_lock);
		else
			got_lock = osd_lock_try(window->render_lock);

		// only render if we were able to get the lock
		if (got_lock)
		{
			const render_primitive_list *primlist;

			mtlog_add("winwindow_video_window_update: got lock");

			// don't hold the lock; we just used it to see if rendering was still happening
			osd_lock_release(window->render_lock);

			// ensure the target bounds are up-to-date, and then get the primitives
			primlist = (*draw.window_get_primitives)(window);

			// post a redraw request with the primitive list as a parameter
			last_update_time = timeGetTime();
			mtlog_add("winwindow_video_window_update: PostMessage start");
			if (multithreading_enabled)
				PostMessage(window->hwnd, WM_USER_REDRAW, 0, (LPARAM)primlist);
			else
				SendMessage(window->hwnd, WM_USER_REDRAW, 0, (LPARAM)primlist);
			mtlog_add("winwindow_video_window_update: PostMessage end");
		}
	}

	mtlog_add("winwindow_video_window_update: end");
}
Beispiel #3
0
void sdlwindow_blit_surface_size(sdl_window_info *window, int window_width, int window_height)
{
	INT32 newwidth, newheight;
	int xscale = 1, yscale = 1;
	float desired_aspect = 1.0f;
	INT32 target_width = window_width;
	INT32 target_height = window_height;

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

	// compute the appropriate visible area if we're trying to keepaspect
	if (video_config.keepaspect)
	{
		// make sure the monitor is up-to-date
		sdlvideo_monitor_refresh(window->monitor);
		render_target_compute_visible_area(window->target, target_width, target_height, sdlvideo_monitor_get_aspect(window->monitor), render_target_get_orientation(window->target), &target_width, &target_height);
		desired_aspect = (float)target_width / (float)target_height;
	}

    // non-integer scaling - often gives more pleasing results in full screen
    if (!video_config.fullstretch)
	{
		// 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) <= window_width &&
				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) <= window_height &&
				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 (window_width - newwidth * xscale < window_height - newheight * yscale)
			{
				while (better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale - 1), newheight * yscale, desired_aspect) && (xscale >= 0))
					xscale--;
			}
			else
			{
				while (better_mode(newwidth * xscale, newheight * yscale, newwidth * xscale, newheight * (yscale - 1), desired_aspect) && (yscale >= 0))
					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;
	}
	else
	{
		newwidth = target_width;
		newheight = target_height;
	}

    //FIXME: really necessary to distinguish for yuv_modes ?
	if ((render_target_get_layer_config(window->target) & LAYER_CONFIG_ZOOM_TO_SCREEN)
		&& (window->scale_mode == VIDEO_SCALE_MODE_NONE ))
		newwidth = window_width;

	if ((window->blitwidth != newwidth) || (window->blitheight != newheight))
		sdlwindow_clear(window);

	window->blitwidth = newwidth;
	window->blitheight = newheight;
}