void osd_update(running_machine *machine, int skip_redraw){ nitroinput_update(); const render_primitive_list *primlist; int minwidth, minheight; // get the minimum width/height for the current layout render_target_get_minimum_size(our_target, &minwidth, &minheight); if(our_target){ // make that the size of our target render_target_set_bounds(our_target, minwidth, minheight, 0); // get the list of primitives for the target at the current size primlist = render_target_get_primitives(our_target); // lock them, and then render them osd_lock_acquire(primlist->lock); // do the drawing here osd_lock_release(primlist->lock); } // after 5 seconds, exit if (attotime_compare(timer_get_time(machine), attotime_make(5, 0)) > 0) mame_schedule_exit(machine); }
void droid_video_render(render_target *our_target) { int minwidth, minheight; pthread_mutex_lock( &cond_mutex ); if(currlist==NULL) { // get the minimum width/height for the current layout render_target_get_minimum_size(our_target, &minwidth, &minheight); if(minwidth%2!=0)minwidth++; // make that the size of our target render_target_set_bounds(our_target, minwidth, minheight, 0); currlist = render_target_get_primitives(our_target); curr_screen_width = minwidth; curr_screen_height = minheight; pthread_cond_signal( &condition_var ); } pthread_mutex_unlock( &cond_mutex ); }
static void get_min_bounds(win_window_info *window, RECT *bounds, int constrain) { INT32 minwidth, minheight; assert(GetCurrentThreadId() == window_threadid); // get the minimum target size render_target_get_minimum_size(window->target, &minwidth, &minheight); // expand to our minimum dimensions if (minwidth < MIN_WINDOW_DIM) minwidth = MIN_WINDOW_DIM; if (minheight < MIN_WINDOW_DIM) minheight = MIN_WINDOW_DIM; // account for extra window stuff minwidth += wnd_extra_width(window); minheight += wnd_extra_height(window); // if we want it constrained, figure out which one is larger if (constrain) { RECT test1, test2; // first constrain with no height limit test1.top = test1.left = 0; test1.right = minwidth; test1.bottom = 10000; constrain_to_aspect_ratio(window, &test1, WMSZ_BOTTOMRIGHT); // then constrain with no width limit test2.top = test2.left = 0; test2.right = 10000; test2.bottom = minheight; constrain_to_aspect_ratio(window, &test2, WMSZ_BOTTOMRIGHT); // pick the larger if (rect_width(&test1) > rect_width(&test2)) { minwidth = rect_width(&test1); minheight = rect_height(&test1); } else { minwidth = rect_width(&test2); minheight = rect_height(&test2); } } // get the window rect GetWindowRect(window->hwnd, bounds); // now adjust bounds->right = bounds->left + minwidth; bounds->bottom = bounds->top + minheight; }
void sdlwindow_video_window_update(running_machine *machine, sdl_window_info *window) { ASSERT_MAIN_THREAD(); // adjust the cursor state sdlwindow_update_cursor_state(machine, window); // if we're visible and running and not in the middle of a resize, draw if (window->target != NULL) { int tempwidth, tempheight; // see if the games video mode has changed render_target_get_minimum_size(window->target, &tempwidth, &tempheight); if (tempwidth != window->minwidth || tempheight != window->minheight) { window->minwidth = tempwidth; window->minheight = tempheight; if (!window->fullscreen) { sdlwindow_blit_surface_size(window, window->width, window->height); sdlwindow_resize(window, window->blitwidth, window->blitheight); } else if (video_config.switchres) { pick_best_mode(window, &tempwidth, &tempheight); sdlwindow_resize(window, tempwidth, tempheight); } } // only render if we have been signalled if (osd_event_wait(window->rendered_event, 0)) { worker_param wp; const render_primitive_list *primlist; clear_worker_param(&wp); // ensure the target bounds are up-to-date, and then get the primitives primlist = window->get_primitives(window); // and redraw now wp.list = primlist; wp.window = window; wp.machine = machine; execute_async(&draw_video_contents_wt, &wp); } } }
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 render_target_get_minimum_size(window->target, &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_config *primary_screen = screen_first(*window->machine->config); if (primary_screen != NULL) einfo.target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh()); 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 mame_printf_verbose(_WINDOWS("DirectDraw: Selecting video mode...\n")); result = IDirectDraw7_EnumDisplayModes(dd->ddraw, DDEDM_REFRESHRATES, NULL, &einfo, enum_modes_callback); if (result != DD_OK) mame_printf_verbose(_WINDOWS("DirectDraw: Error %08X during EnumDisplayModes call\n"), (int)result); mame_printf_verbose(_WINDOWS("DirectDraw: Mode selected = %4dx%4d@%3dHz\n"), dd->width, dd->height, dd->refresh); }
static void get_min_bounds(sdl_window_info *window, int *window_width, int *window_height, int constrain) { INT32 minwidth, minheight; // get the minimum target size render_target_get_minimum_size(window->target, &minwidth, &minheight); // expand to our minimum dimensions if (minwidth < MIN_WINDOW_DIM) minwidth = MIN_WINDOW_DIM; if (minheight < MIN_WINDOW_DIM) minheight = MIN_WINDOW_DIM; // if we want it constrained, figure out which one is larger if (constrain) { int test1w, test1h; int test2w, test2h; // first constrain with no height limit test1w = minwidth; test1h = 10000; constrain_to_aspect_ratio(window, &test1w, &test1h, WMSZ_BOTTOMRIGHT); // then constrain with no width limit test2w = 10000; test2h = minheight; constrain_to_aspect_ratio(window, &test2w, &test2h, WMSZ_BOTTOMRIGHT); // pick the larger if ( test1w > test2w ) { minwidth = test1w; minheight = test1h; } else { minwidth = test2w; minheight = test2h; } } *window_width = minwidth; *window_height = minheight; }
static void save_frame_with(mame_file *fp, int scrnum, png_error (*write_handler)(mame_file *, mame_bitmap *)) { const render_primitive_list *primlist; INT32 width, height; int error; assert(scrnum >= 0 && scrnum < MAX_SCREENS); /* if no screens, do nothing */ if (snap_target == NULL) return; /* select the appropriate view in our dummy target */ render_target_set_view(snap_target, scrnum); /* get the minimum width/height and set it on the target */ render_target_get_minimum_size(snap_target, &width, &height); render_target_set_bounds(snap_target, width, height, 0); /* if we don't have a bitmap, or if it's not the right size, allocate a new one */ if (snap_bitmap == NULL || width != snap_bitmap->width || height != snap_bitmap->height) { if (snap_bitmap != NULL) bitmap_free(snap_bitmap); snap_bitmap = bitmap_alloc_format(width, height, BITMAP_FORMAT_RGB32); assert(snap_bitmap != NULL); } /* render the screen there */ primlist = render_target_get_primitives(snap_target); osd_lock_acquire(primlist->lock); rgb888_draw_primitives(primlist->head, snap_bitmap->base, width, height, snap_bitmap->rowpixels); osd_lock_release(primlist->lock); /* now do the actual work */ error = (*write_handler)(fp, snap_bitmap); }
static void compute_blit_surface_size(win_window_info *window) { dd_info *dd = window->drawdata; INT32 newwidth, newheight; int xscale, yscale; RECT client; // start with the minimum size render_target_get_minimum_size(window->target, &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); render_target_compute_visible_area(window->target, target_width, target_height, winvideo_monitor_get_aspect(monitor), render_target_get_orientation(window->target), &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); mame_printf_verbose("DirectDraw: New blit size = %dx%d\n", newwidth, newheight); } dd->blitwidth = newwidth; dd->blitheight = newheight; }
static void constrain_to_aspect_ratio(win_window_info *window, RECT *rect, int adjustment) { win_monitor_info *monitor = winwindow_video_window_monitor(window, rect); INT32 extrawidth = wnd_extra_width(window); INT32 extraheight = wnd_extra_height(window); INT32 propwidth, propheight; INT32 minwidth, minheight; INT32 maxwidth, maxheight; INT32 viswidth, visheight; INT32 adjwidth, adjheight; float pixel_aspect; assert(GetCurrentThreadId() == window_threadid); // get the pixel aspect ratio for the target monitor pixel_aspect = winvideo_monitor_get_aspect(monitor); // determine the proposed width/height propwidth = rect_width(rect) - extrawidth; propheight = rect_height(rect) - extraheight; // based on which edge we are adjusting, take either the width, height, or both as gospel // and scale to fit using that as our parameter switch (adjustment) { case WMSZ_BOTTOM: case WMSZ_TOP: render_target_compute_visible_area(window->target, 10000, propheight, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); break; case WMSZ_LEFT: case WMSZ_RIGHT: render_target_compute_visible_area(window->target, propwidth, 10000, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); break; default: render_target_compute_visible_area(window->target, propwidth, propheight, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); break; } // get the minimum width/height for the current layout render_target_get_minimum_size(window->target, &minwidth, &minheight); // clamp against the absolute minimum propwidth = MAX(propwidth, MIN_WINDOW_DIM); propheight = MAX(propheight, MIN_WINDOW_DIM); // clamp against the minimum width and height propwidth = MAX(propwidth, minwidth); propheight = MAX(propheight, minheight); // clamp against the maximum (fit on one screen for full screen mode) if (window->fullscreen) { maxwidth = rect_width(&monitor->info.rcMonitor) - extrawidth; maxheight = rect_height(&monitor->info.rcMonitor) - extraheight; } else { maxwidth = rect_width(&monitor->info.rcWork) - extrawidth; maxheight = rect_height(&monitor->info.rcWork) - extraheight; // further clamp to the maximum width/height in the window if (window->maxwidth != 0) maxwidth = MIN(maxwidth, window->maxwidth + extrawidth); if (window->maxheight != 0) maxheight = MIN(maxheight, window->maxheight + extraheight); } // clamp to the maximum propwidth = MIN(propwidth, maxwidth); propheight = MIN(propheight, maxheight); // compute the visible area based on the proposed rectangle render_target_compute_visible_area(window->target, propwidth, propheight, pixel_aspect, render_target_get_orientation(window->target), &viswidth, &visheight); // compute the adjustments we need to make adjwidth = (viswidth + extrawidth) - rect_width(rect); adjheight = (visheight + extraheight) - rect_height(rect); // based on which corner we're adjusting, constrain in different ways switch (adjustment) { case WMSZ_BOTTOM: case WMSZ_BOTTOMRIGHT: case WMSZ_RIGHT: rect->right += adjwidth; rect->bottom += adjheight; break; case WMSZ_BOTTOMLEFT: rect->left -= adjwidth; rect->bottom += adjheight; break; case WMSZ_LEFT: case WMSZ_TOPLEFT: case WMSZ_TOP: rect->left -= adjwidth; rect->top -= adjheight; break; case WMSZ_TOPRIGHT: rect->right += adjwidth; rect->top -= adjheight; break; } }
void droid_ios_video_render(render_target *our_target) { int width, height; int minwidth, minheight; int viswidth, visheight; int aspect; if(myosd_video_threaded) pthread_mutex_lock( &cond_mutex ); if(currlist==NULL) { if(!myosd_inGame) { width = viswidth = myosd_res_width; height = visheight = myosd_res_height; aspect = 0; } else if(myosd_force_pxaspect == 1) { render_target_get_minimum_size(our_target, &minwidth, &minheight); width = minwidth; height = minheight; viswidth = minwidth; visheight = minheight; aspect = 0; } else if(myosd_force_pxaspect==2) { render_target_get_minimum_size(our_target, &minwidth, &minheight); width = minwidth; height = minheight; viswidth = minwidth; visheight = minheight; int w,h; render_target_compute_visible_area(our_target,minwidth,minheight,1,render_target_get_orientation(our_target),&w, &h); if(visheight > h && abs((float)w/(float)h - 4.0f/3.0f) < 0.001)// 4/3 minimum { viswidth = w; visheight = h; } if(viswidth > h * 16.0f/9.0f && abs((float)w/(float)h - 4.0f/3.0f) < 0.001)// 16/9 maximun { viswidth = h * 16.0f/9.0f; visheight = h; } if(viswidth < w && abs((float)w/(float)h - 3.0f/4.0f) < 0.001)// 3/4 minimum { viswidth = w; visheight = h; } if(visheight > h && abs((float)w/(float)h - 3.0f/4.0f) < 0.001)// 3/4 maximun { viswidth = w ; visheight = h; } aspect = 0; #ifdef ANDROID // __android_log_print(ANDROID_LOG_DEBUG, "VIS","FIN %d, %d",viswidth,visheight); #endif } else //MAME standard { if(myosd_auto_res==1) { render_target_get_minimum_size(our_target, &width, &height); if(width > 640) { if(myosd_res_width > 640) width = myosd_res_width; else width = 640; } if(height > 480) { if(myosd_res_height > 480) height = myosd_res_height; else height = 480; } //calculate vis area to pass to GPU scaler instead MAME scaler. Performace and accurate! render_target_compute_visible_area(our_target,width,height,1,render_target_get_orientation(our_target),&viswidth, &visheight); aspect = 0; } else { width = myosd_res_width; height = myosd_res_height; viswidth = width ; visheight = height; aspect = width / height; } } if(width%2!=0)width++; // make that the size of our target render_target_set_bounds(our_target, width, height, aspect); currlist = render_target_get_primitives(our_target); curr_screen_width = width; curr_screen_height = height; curr_vis_area_screen_width = viswidth; curr_vis_area_screen_height = visheight; if(myosd_video_threaded) pthread_cond_signal( &condition_var ); else droid_ios_video_draw(); } if(myosd_video_threaded) pthread_mutex_unlock( &cond_mutex ); }
static void pick_best_mode(sdl_window_info *window, int *fswidth, int *fsheight) { int minimum_width, minimum_height, target_width, target_height; int i; float size_score, best_score = 0.0f; SDL_Rect **modes; // determine the minimum width/height for the selected target render_target_get_minimum_size(window->target, &minimum_width, &minimum_height); // use those as the target for now target_width = minimum_width * MAX(1, window->prescale); target_height = minimum_height * MAX(1, window->prescale); // if we're not stretching, allow some slop on the minimum since we can handle it { minimum_width -= 4; minimum_height -= 4; } #if 1 // defined(SDLMAME_WIN32) /* * We need to do this here. If SDL_ListModes is * called in init_monitors, the call will crash * on win32 */ modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_DOUBLEBUF); #else modes = window->monitor->modes; #endif if (modes == (SDL_Rect **)0) { mame_printf_error("SDL: No modes available?!\n"); exit(-1); } else if (modes == (SDL_Rect **)-1) // all modes are possible { *fswidth = window->maxwidth; *fsheight = window->maxheight; } else { for (i = 0; modes[i]; ++i) { // compute initial score based on difference between target and current size_score = 1.0f / (1.0f + fabsf((INT32)modes[i]->w - target_width) + fabsf((INT32)modes[i]->h - target_height)); // if the mode is too small, give a big penalty if (modes[i]->w < minimum_width || modes[i]->h < minimum_height) size_score *= 0.01f; // if mode is smaller than we'd like, it only scores up to 0.1 if (modes[i]->w < target_width || modes[i]->h < target_height) size_score *= 0.1f; // if we're looking for a particular mode, that's a winner if (modes[i]->w == window->maxwidth && modes[i]->h == window->maxheight) size_score = 2.0f; mame_printf_verbose("%4dx%4d -> %f\n", (int)modes[i]->w, (int)modes[i]->h, size_score); // best so far? if (size_score > best_score) { best_score = size_score; *fswidth = modes[i]->w; *fsheight = modes[i]->h; } } } }
static void pick_best_mode(sdl_window_info *window, int *fswidth, int *fsheight) { int minimum_width, minimum_height, target_width, target_height; int i; int num; float size_score, best_score = 0.0f; // determine the minimum width/height for the selected target render_target_get_minimum_size(window->target, &minimum_width, &minimum_height); // use those as the target for now target_width = minimum_width * MAX(1, window->prescale); target_height = minimum_height * MAX(1, window->prescale); // if we're not stretching, allow some slop on the minimum since we can handle it { minimum_width -= 4; minimum_height -= 4; } num = SDL_GetNumDisplayModes(); if (num == 0) { mame_printf_error("SDL: No modes available?!\n"); exit(-1); } else { for (i = 0; i < num; ++i) { SDL_DisplayMode mode; SDL_GetDisplayMode(i, &mode); // compute initial score based on difference between target and current size_score = 1.0f / (1.0f + fabsf((INT32)mode.w - target_width) + fabsf((INT32)mode.h - target_height)); // if the mode is too small, give a big penalty if (mode.w < minimum_width || mode.h < minimum_height) size_score *= 0.01f; // if mode is smaller than we'd like, it only scores up to 0.1 if (mode.w < target_width || mode.h < target_height) size_score *= 0.1f; // if we're looking for a particular mode, that's a winner if (mode.w == window->maxwidth && mode.h == window->maxheight) size_score = 2.0f; // refresh adds some points if (window->refresh) size_score *= 1.0f / (1.0f + fabsf(window->refresh - mode.refresh_rate) / 10.0f); mame_printf_verbose("%4dx%4d@%2d -> %f\n", (int)mode.w, (int)mode.h, (int) mode.refresh_rate, size_score); // best so far? if (size_score > best_score) { best_score = size_score; *fswidth = mode.w; *fsheight = mode.h; } } } }
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; }
static void constrain_to_aspect_ratio(sdl_window_info *window, int *window_width, int *window_height, int adjustment) { INT32 extrawidth = 0; INT32 extraheight = 0; INT32 propwidth, propheight; INT32 minwidth, minheight; INT32 maxwidth, maxheight; INT32 viswidth, visheight; float pixel_aspect; // make sure the monitor is up-to-date sdlvideo_monitor_refresh(window->monitor); // get the pixel aspect ratio for the target monitor pixel_aspect = sdlvideo_monitor_get_aspect(window->monitor); // determine the proposed width/height propwidth = *window_width - extrawidth; propheight = *window_height - extraheight; // based on which edge we are adjusting, take either the width, height, or both as gospel // and scale to fit using that as our parameter switch (adjustment) { case WMSZ_BOTTOM: case WMSZ_TOP: render_target_compute_visible_area(window->target, 10000, propheight, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); break; case WMSZ_LEFT: case WMSZ_RIGHT: render_target_compute_visible_area(window->target, propwidth, 10000, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); break; default: render_target_compute_visible_area(window->target, propwidth, propheight, pixel_aspect, render_target_get_orientation(window->target), &propwidth, &propheight); break; } // get the minimum width/height for the current layout render_target_get_minimum_size(window->target, &minwidth, &minheight); // clamp against the absolute minimum propwidth = MAX(propwidth, MIN_WINDOW_DIM); propheight = MAX(propheight, MIN_WINDOW_DIM); // clamp against the minimum width and height propwidth = MAX(propwidth, minwidth); propheight = MAX(propheight, minheight); // clamp against the maximum (fit on one screen for full screen mode) if (window->fullscreen) { maxwidth = window->monitor->center_width - extrawidth; maxheight = window->monitor->center_height - extraheight; } else { maxwidth = window->monitor->center_width - extrawidth; maxheight = window->monitor->center_height - extraheight; // further clamp to the maximum width/height in the window if (window->maxwidth != 0) maxwidth = MIN(maxwidth, window->maxwidth + extrawidth); if (window->maxheight != 0) maxheight = MIN(maxheight, window->maxheight + extraheight); } // clamp to the maximum propwidth = MIN(propwidth, maxwidth); propheight = MIN(propheight, maxheight); // compute the visible area based on the proposed rectangle render_target_compute_visible_area(window->target, propwidth, propheight, pixel_aspect, render_target_get_orientation(window->target), &viswidth, &visheight); *window_width = viswidth; *window_height = visheight; }