osd_dim sdl_window_info::get_max_bounds(int constrain) { //assert(GetCurrentThreadId() == window_threadid); // compute the maximum client area // m_monitor->refresh(); osd_rect maximum = m_monitor->usuable_position_size(); // clamp to the window's max int tempw = maximum.width(); int temph = maximum.height(); if (m_win_config.width != 0) { int temp = m_win_config.width + wnd_extra_width(); if (temp < maximum.width()) tempw = temp; } if (m_win_config.height != 0) { int temp = m_win_config.height + wnd_extra_height(); if (temp < maximum.height()) temph = temp; } maximum = maximum.resize(tempw, temph); // constrain to fit if (constrain) maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT); else { maximum = maximum.resize(maximum.width() - wnd_extra_width(), maximum.height() - wnd_extra_height()); } return maximum.dim(); }
osd_dim sdl_window_info::get_min_bounds(int constrain) { INT32 minwidth, minheight; //assert(GetCurrentThreadId() == window_threadid); // get the minimum target size m_target->compute_minimum_size(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(); minheight += wnd_extra_height(); // if we want it constrained, figure out which one is larger if (constrain) { // first constrain with no height limit osd_rect test1(0,0,minwidth,10000); test1 = constrain_to_aspect_ratio(test1, WMSZ_BOTTOMRIGHT); // then constrain with no width limit osd_rect test2(0,0,10000,minheight); test2 = constrain_to_aspect_ratio(test2, WMSZ_BOTTOMRIGHT); // pick the larger if (test1.width() > test2.width()) { minwidth = test1.width(); minheight = test1.height(); } else { minwidth = test2.width(); minheight = test2.height(); } } // remove extra window stuff minwidth -= wnd_extra_width(); minheight -= wnd_extra_height(); return osd_dim(minwidth, minheight); }
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; }
static void get_max_bounds(win_window_info *window, RECT *bounds, int constrain) { RECT maximum; assert(GetCurrentThreadId() == window_threadid); // compute the maximum client area winvideo_monitor_refresh(window->monitor); maximum = window->monitor->info.rcWork; // clamp to the window's max if (window->maxwidth != 0) { int temp = window->maxwidth + wnd_extra_width(window); if (temp < rect_width(&maximum)) maximum.right = maximum.left + temp; } if (window->maxheight != 0) { int temp = window->maxheight + wnd_extra_height(window); if (temp < rect_height(&maximum)) maximum.bottom = maximum.top + temp; } // constrain to fit if (constrain) constrain_to_aspect_ratio(window, &maximum, WMSZ_BOTTOMRIGHT); else { maximum.right -= wnd_extra_width(window); maximum.bottom -= wnd_extra_height(window); } // center within the work area bounds->left = window->monitor->info.rcWork.left + (rect_width(&window->monitor->info.rcWork) - rect_width(&maximum)) / 2; bounds->top = window->monitor->info.rcWork.top + (rect_height(&window->monitor->info.rcWork) - rect_height(&maximum)) / 2; bounds->right = bounds->left + rect_width(&maximum); bounds->bottom = bounds->top + rect_height(&maximum); }
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; } }
static int complete_create(win_window_info *window) { TCHAR *t_title; RECT monitorbounds, client; int tempwidth, tempheight; HMENU menu = NULL; HDC dc; assert(GetCurrentThreadId() == window_threadid); // get the monitor bounds monitorbounds = window->monitor->info.rcMonitor; // create the window menu if needed #if HAS_WINDOW_MENU if (win_create_menu(&menu)) return 1; #endif // create the window, but don't show it yet t_title = tstring_from_utf8(window->title); if (t_title == NULL) return 1; window->hwnd = CreateWindowEx( window->fullscreen ? FULLSCREEN_STYLE_EX : WINDOW_STYLE_EX, TEXT("MAME"), t_title, window->fullscreen ? FULLSCREEN_STYLE : WINDOW_STYLE, monitorbounds.left + 20, monitorbounds.top + 20, monitorbounds.left + 100, monitorbounds.top + 100, NULL,//(win_window_list != NULL) ? win_window_list->hwnd : NULL, menu, GetModuleHandle(NULL), NULL); free(t_title); if (window->hwnd == NULL) return 1; // set a pointer back to us SetWindowLongPtr(window->hwnd, GWLP_USERDATA, (LONG_PTR)window); // adjust the window position to the initial width/height tempwidth = (window->maxwidth != 0) ? window->maxwidth : 640; tempheight = (window->maxheight != 0) ? window->maxheight : 480; SetWindowPos(window->hwnd, NULL, monitorbounds.left + 20, monitorbounds.top + 20, monitorbounds.left + tempwidth + wnd_extra_width(window), monitorbounds.top + tempheight + wnd_extra_height(window), SWP_NOZORDER); // maximum or minimize as appropriate if (window->startmaximized) maximize_window(window); else minimize_window(window); adjust_window_position_after_major_change(window); // show the window if (!window->fullscreen || window->fullscreen_safe) { // finish off by trying to initialize DirectX; if we fail, ignore it if ((*draw.window_init)(window)) return 1; if (video_config.mode != VIDEO_MODE_NONE) ShowWindow(window->hwnd, SW_SHOW); } // clear the window dc = GetDC(window->hwnd); GetClientRect(window->hwnd, &client); FillRect(dc, &client, (HBRUSH)GetStockObject(BLACK_BRUSH)); ReleaseDC(window->hwnd, dc); return 0; }
osd_rect sdl_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int adjustment) { INT32 extrawidth = wnd_extra_width(); INT32 extraheight = wnd_extra_height(); INT32 propwidth, propheight; INT32 minwidth, minheight; INT32 maxwidth, maxheight; INT32 viswidth, visheight; INT32 adjwidth, adjheight; float pixel_aspect; osd_monitor_info *monitor = m_monitor; // get the pixel aspect ratio for the target monitor pixel_aspect = monitor->aspect(); // determine the proposed width/height propwidth = rect.width() - extrawidth; propheight = rect.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: m_target->compute_visible_area(10000, propheight, pixel_aspect, m_target->orientation(), propwidth, propheight); break; case WMSZ_LEFT: case WMSZ_RIGHT: m_target->compute_visible_area(propwidth, 10000, pixel_aspect, m_target->orientation(), propwidth, propheight); break; default: m_target->compute_visible_area(propwidth, propheight, pixel_aspect, m_target->orientation(), propwidth, propheight); break; } // get the minimum width/height for the current layout m_target->compute_minimum_size(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 (m_fullscreen) { maxwidth = monitor->position_size().width() - extrawidth; maxheight = monitor->position_size().height() - extraheight; } else { maxwidth = monitor->usuable_position_size().width() - extrawidth; maxheight = monitor->usuable_position_size().height() - extraheight; // further clamp to the maximum width/height in the window if (m_win_config.width != 0) maxwidth = MIN(maxwidth, m_win_config.width + extrawidth); if (m_win_config.height != 0) maxheight = MIN(maxheight, m_win_config.height + extraheight); } // clamp to the maximum propwidth = MIN(propwidth, maxwidth); propheight = MIN(propheight, maxheight); // compute the visible area based on the proposed rectangle m_target->compute_visible_area(propwidth, propheight, pixel_aspect, m_target->orientation(), viswidth, visheight); // compute the adjustments we need to make adjwidth = (viswidth + extrawidth) - rect.width(); adjheight = (visheight + extraheight) - rect.height(); // based on which corner we're adjusting, constrain in different ways osd_rect ret(rect); switch (adjustment) { case WMSZ_BOTTOM: case WMSZ_BOTTOMRIGHT: case WMSZ_RIGHT: ret = rect.resize(rect.width() + adjwidth, rect.height() + adjheight); break; case WMSZ_BOTTOMLEFT: ret = rect.move_by(-adjwidth, 0).resize(rect.width() + adjwidth, rect.height() + adjheight); break; case WMSZ_LEFT: case WMSZ_TOPLEFT: case WMSZ_TOP: ret = rect.move_by(-adjwidth, -adjheight).resize(rect.width() + adjwidth, rect.height() + adjheight); break; case WMSZ_TOPRIGHT: ret = rect.move_by(0, -adjheight).resize(rect.width() + adjwidth, rect.height() + adjheight); break; } return ret; }