From b77fbed384866279f74b64fc0ff65b01a9e2897b Mon Sep 17 00:00:00 2001 From: couriersud Date: Fri, 27 Feb 2015 00:19:41 +0100 Subject: [PATCH] Introduced osd_rect and osd_dim to allow for more code alignment. (nw) --- src/osd/modules/osdwindow.h | 4 +- src/osd/sdl/draw13.c | 13 +-- src/osd/sdl/drawogl.c | 9 +- src/osd/sdl/drawsdl.c | 15 ++- src/osd/sdl/video.h | 52 ++++++++- src/osd/sdl/window.c | 222 +++++++++++++++++++++--------------- src/osd/sdl/window.h | 27 +++-- src/osd/windows/drawdd.c | 10 +- src/osd/windows/video.h | 55 ++++++++- src/osd/windows/window.c | 191 ++++++++++++++++--------------- src/osd/windows/window.h | 10 +- 11 files changed, 375 insertions(+), 233 deletions(-) diff --git a/src/osd/modules/osdwindow.h b/src/osd/modules/osdwindow.h index 0f55551adc8..c9fdf908248 100644 --- a/src/osd/modules/osdwindow.h +++ b/src/osd/modules/osdwindow.h @@ -51,7 +51,7 @@ public: float aspect() const { return monitor()->aspect(); } - virtual void get_size(int &w, int &h) = 0; + virtual osd_dim get_size() = 0; #ifdef OSD_SDL virtual void blit_surface_size(int &blitwidth, int &blitheight) = 0; @@ -65,7 +65,7 @@ public: virtual win_monitor_info *monitor() const = 0; virtual bool win_has_menu() = 0; // FIXME: cann we replace winwindow_video_window_monitor(NULL) with monitor() ? - virtual win_monitor_info *winwindow_video_window_monitor(const RECT *proposed) = 0; + virtual win_monitor_info *winwindow_video_window_monitor(const osd_rect *proposed) = 0; // window handle and info HWND m_hwnd; diff --git a/src/osd/sdl/draw13.c b/src/osd/sdl/draw13.c index fdb02c010e5..c3231940f5c 100644 --- a/src/osd/sdl/draw13.c +++ b/src/osd/sdl/draw13.c @@ -688,14 +688,13 @@ int sdl_info13::draw(int update) return 0; } - int width = 0; int height = 0; - window().get_size(width,height); + osd_dim wdim = window().get_size(); - if (has_flags(FI_CHANGED) || (width != m_width) || (height != m_height)) + if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height)) { destroy_all_textures(); - m_width = width; - m_height = height; + m_width = wdim.width(); + m_height = wdim.height(); SDL_RenderSetViewport(m_sdl_renderer, NULL); m_blittimer = 3; clear_flags(FI_CHANGED); @@ -720,8 +719,8 @@ int sdl_info13::draw(int update) { int ch, cw; - ch = height; - cw = width; + ch = wdim.height(); + cw = wdim.width(); if (video_config.centerv) { diff --git a/src/osd/sdl/drawogl.c b/src/osd/sdl/drawogl.c index 12fbe9891df..d6b509b94cf 100644 --- a/src/osd/sdl/drawogl.c +++ b/src/osd/sdl/drawogl.c @@ -1479,7 +1479,6 @@ int sdl_info_ogl::draw(const int update) texture_info *texture=NULL; float vofs, hofs; int pendingPrimitive=GL_NO_PRIMITIVE, curPrimitive=GL_NO_PRIMITIVE; - int width = 0; int height = 0; #ifdef TOBEMIGRATED if (video_config.novideo) @@ -1488,13 +1487,13 @@ int sdl_info_ogl::draw(const int update) } #endif - window().get_size(width, height); + osd_dim wdim = window().get_size(); - if (has_flags(FI_CHANGED) || (width != m_width) || (height != m_height)) + if (has_flags(FI_CHANGED) || (wdim.width() != m_width) || (wdim.height() != m_height)) { destroy_all_textures(); - m_width = width; - m_height = height; + m_width = wdim.width(); + m_height = wdim.height(); m_blittimer = 3; m_init_context = 1; clear_flags(FI_CHANGED); diff --git a/src/osd/sdl/drawsdl.c b/src/osd/sdl/drawsdl.c index 45ac54fa64b..1d544c2d55e 100644 --- a/src/osd/sdl/drawsdl.c +++ b/src/osd/sdl/drawsdl.c @@ -559,7 +559,6 @@ int sdl_info::draw(int update) UINT8 *surfptr; INT32 pitch; Uint32 rmask, gmask, bmask; - int width = 0; int height = 0; #if (SDLMAME_SDL2) Uint32 amask; #endif @@ -571,14 +570,14 @@ int sdl_info::draw(int update) return 0; } - window().get_size(width, height); - if (has_flags(FI_CHANGED) || (width != m_last_width) || (height != m_last_height)) + osd_dim wdim = window().get_size(); + if (has_flags(FI_CHANGED) || (wdim.width() != m_last_width) || (wdim.height() != m_last_height)) { destroy_all_textures(); clear_flags(FI_CHANGED); m_blittimer = 3; - m_last_width = width; - m_last_height = height; + m_last_width = wdim.width(); + m_last_height = wdim.height(); #if (SDLMAME_SDL2) SDL_RenderSetViewport(m_sdl_renderer, NULL); if (m_texture_id != NULL) @@ -619,7 +618,7 @@ int sdl_info::draw(int update) // Clear if necessary if (m_blittimer > 0) { - memset(window().sdl_surface()->pixels, 0, height * window().sdl_surface()->pitch); + memset(window().sdl_surface()->pixels, 0, wdim.height() * window().sdl_surface()->pitch); m_blittimer--; } @@ -669,8 +668,8 @@ int sdl_info::draw(int update) blitwidth = m_blitwidth; blitheight = m_blitheight; - ch = height; - cw = width; + ch = wdim.height(); + cw = wdim.width(); // do not crash if the window's smaller than the blit area if (blitheight > ch) diff --git a/src/osd/sdl/video.h b/src/osd/sdl/video.h index 01a6caa9ee6..68ae3d2f72d 100644 --- a/src/osd/sdl/video.h +++ b/src/osd/sdl/video.h @@ -59,6 +59,56 @@ struct sdl_mode int height; }; +class osd_dim +{ +public: + osd_dim(const int &w, const int &h) + : m_w(w), m_h(h) + { + } + int width() const { return m_w; } + int height() const { return m_h; } + +private: + int m_w; + int m_h; +}; + +class osd_rect +{ +public: + osd_rect(const int x, const int y, const int &w, const int &h) + : m_x(x), m_y(y), m_d(w,h) + { + } + osd_rect(const int x, const int y, const osd_dim &d) + : m_x(x), m_y(y), m_d(d) + { + } + int top() const { return m_y; } + int left() const { return m_x; } + int width() const { return m_d.width(); } + int height() const { return m_d.height(); } + + osd_dim dim() const { return m_d; } + + int bottom() const { return m_y + m_d.height(); } + int right() const { return m_x + m_d.width(); } + + osd_rect move_by(int dx, int dy) const { return osd_rect(m_x + dx, m_y + dy, m_d); } + osd_rect resize(int w, int h) const { return osd_rect(m_x, m_y, w, h); } + +private: + int m_x; + int m_y; + osd_dim m_d; +}; + +inline osd_rect SDL_Rect_to_osd_rect(const SDL_Rect &r) +{ + return osd_rect(r.x, r.y, r.w, r.h); +} + // FIXME: This is sort of ugly ... and should be a real interface only class sdl_monitor_info { @@ -75,7 +125,7 @@ public: } const UINT64 handle() { return m_handle; } - const SDL_Rect &position_size() { refresh(); return m_dimensions; } + const osd_rect position_size() { refresh(); return SDL_Rect_to_osd_rect(m_dimensions); } const char *devicename() { refresh(); return m_name[0] ? m_name : "UNKNOWN"; } diff --git a/src/osd/sdl/window.c b/src/osd/sdl/window.c index 71054ce32b3..7e368b873c6 100644 --- a/src/osd/sdl/window.c +++ b/src/osd/sdl/window.c @@ -384,14 +384,13 @@ INLINE int better_mode(int width0, int height0, int width1, int height1, float d void sdl_window_info::blit_surface_size(int &blitwidth, int &blitheight) { - int window_width, window_height; - get_size(window_width, window_height); + osd_dim window_dim = get_size(); - INT32 newwidth, newheight; + int newwidth, newheight; int xscale = 1, yscale = 1; float desired_aspect = 1.0f; - INT32 target_width = window_width; - INT32 target_height = window_height; + INT32 target_width = window_dim.width(); + INT32 target_height = window_dim.height(); // start with the minimum size m_target->compute_minimum_size(newwidth, newheight); @@ -415,17 +414,17 @@ void sdl_window_info::blit_surface_size(int &blitwidth, int &blitheight) 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 && + while (newwidth * (xscale + 1) <= window_dim.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 && + while (newheight * (yscale + 1) <= window_dim.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) + if (window_dim.width() - newwidth * xscale < window_dim.height() - newheight * yscale) { while (better_mode(newwidth * xscale, newheight * yscale, newwidth * (xscale - 1), newheight * yscale, desired_aspect) && (xscale >= 0)) xscale--; @@ -454,13 +453,8 @@ void sdl_window_info::blit_surface_size(int &blitwidth, int &blitheight) //FIXME: really necessary to distinguish for yuv_modes ? if (m_target->zoom_to_screen() && (video_config.scale_mode == VIDEO_SCALE_MODE_NONE )) - newwidth = window_width; + newwidth = window_dim.width(); -#if 0 - // Fixme: notify_changed really necessary ? - if ((blitwidth != newwidth) || (blitheight != newheight)) - notify_changed(); -#endif blitwidth = newwidth; blitheight = newheight; } @@ -498,10 +492,9 @@ void sdl_window_info::resize(INT32 width, INT32 height) { ASSERT_MAIN_THREAD(); - int cw=0; int ch=0; - get_size(cw, ch); + osd_dim cd = get_size(); - if (width != cw || height != ch) + if (width != cd.width() || height != cd.height()) execute_async_wait(&sdlwindow_resize_wt, worker_param(this, width, height)); } @@ -555,7 +548,7 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt ) // If we are going fullscreen (leaving windowed) remember our windowed size if (!window->fullscreen()) { - window->get_size(window->m_windowed_width, window->m_windowed_height); + window->m_windowed_dim = window->get_size(); } window->renderer().destroy(); @@ -853,7 +846,7 @@ void sdl_window_info::destroy() //============================================================ #if SDLMAME_SDL2 -void sdl_window_info::pick_best_mode(int *fswidth, int *fsheight) +osd_dim sdl_window_info::pick_best_mode() { int minimum_width, minimum_height, target_width, target_height; int i; @@ -912,15 +905,15 @@ void sdl_window_info::pick_best_mode(int *fswidth, int *fsheight) if (size_score > best_score) { best_score = size_score; - *fswidth = mode.w; - *fsheight = mode.h; + return osd_dim(mode.w, mode.h); } } } + return osd_dim(0,0); // please compiler } #else -void sdl_window_info::pick_best_mode(int *fswidth, int *fsheight) +osd_dim sdl_window_info::pick_best_mode() { int minimum_width, minimum_height, target_width, target_height; int i; @@ -958,8 +951,7 @@ void sdl_window_info::pick_best_mode(int *fswidth, int *fsheight) } else if (modes == (SDL_Rect **)-1) // all modes are possible { - *fswidth = m_win_config.width; - *fsheight = m_win_config.height; + return osd_dim(m_win_config.width, m_win_config.height); } else { @@ -986,12 +978,12 @@ void sdl_window_info::pick_best_mode(int *fswidth, int *fsheight) if (size_score > best_score) { best_score = size_score; - *fswidth = modes[i]->w; - *fsheight = modes[i]->h; + return osd_dim(modes[i]->w, modes[i]->h); } } } + return osd_dim(0,0); } #endif @@ -1029,8 +1021,8 @@ void sdl_window_info::update() } else if (video_config.switchres) { - this->pick_best_mode(&tempwidth, &tempheight); - resize(tempwidth, tempheight); + osd_dim tmp = this->pick_best_mode(); + resize(tmp.width(), tmp.height()); } } @@ -1086,7 +1078,7 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) worker_param * wp = (worker_param *) param; sdl_window_info * window = wp->window(); - int tempwidth, tempheight; + osd_dim temp(0,0); static int result[2] = {0,1}; ASSERT_WINDOW_THREAD(); @@ -1095,36 +1087,35 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) if (window->fullscreen()) { // default to the current mode exactly - tempwidth = window->monitor()->position_size().w; - tempheight = window->monitor()->position_size().h; + temp = window->monitor()->position_size().dim(); // if we're allowed to switch resolutions, override with something better if (video_config.switchres) - window->pick_best_mode(&tempwidth, &tempheight); + temp = window->pick_best_mode(); } - else if (window->m_windowed_width) + else if (window->m_windowed_dim.width() > 0) { // if we have a remembered size force the new window size to it - tempwidth = window->m_windowed_width; - tempheight = window->m_windowed_height; + temp = window->m_windowed_dim; } else { if (window->m_startmaximized) { - tempwidth = tempheight = 0; - window->get_max_bounds(&tempwidth, &tempheight, video_config.keepaspect ); + temp = window->get_max_bounds(video_config.keepaspect ); } else { +#if 0 + // Couriersud: This code never has worked with the last version of get_min_bounds /* Create the window directly with the correct aspect instead of letting sdlwindow_blit_surface_size() resize it this stops the window from "flashing" from the wrong aspect size to the right one at startup. */ tempwidth = (window->m_win_config.width != 0) ? window->m_win_config.width : 640; tempheight = (window->m_win_config.height != 0) ? window->m_win_config.height : 480; - - window->get_min_bounds(&tempwidth, &tempheight, video_config.keepaspect ); +#endif + temp = window->get_min_bounds(video_config.keepaspect ); } } @@ -1166,8 +1157,8 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) #endif // create the SDL window window->m_sdl_window = SDL_CreateWindow(window->m_title, - window->monitor()->position_size().x, window->monitor()->position_size().y, - tempwidth, tempheight, window->m_extra_flags); + window->monitor()->position_size().left(), window->monitor()->position_size().top(), + temp.width(), temp.height(), window->m_extra_flags); //window().sdl_window() = SDL_CreateWindow(window().m_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, // width, height, m_extra_flags); @@ -1186,8 +1177,8 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) //SDL_GetCurrentDisplayMode(window().monitor()->handle, &mode); SDL_GetWindowDisplayMode(window->sdl_window(), &mode); window->m_original_mode = mode; - mode.w = tempwidth; - mode.h = tempheight; + mode.w = temp.width(); + mode.h = temp.height(); if (window->m_win_config.refresh) mode.refresh_rate = window->m_win_config.refresh; @@ -1241,7 +1232,7 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt ) if (!window->m_sdlsurf) printf("completely failed\n"); #endif - window->m_sdlsurf = SDL_SetVideoMode(tempwidth, tempheight, + window->m_sdlsurf = SDL_SetVideoMode(temp.width(), temp.height(), 0, SDL_SWSURFACE | SDL_ANYFORMAT | window->m_extra_flags); if (!window->m_sdlsurf) @@ -1377,28 +1368,39 @@ OSDWORK_CALLBACK( sdl_window_info::draw_video_contents_wt ) return NULL; } +int sdl_window_info::wnd_extra_width() +{ + return m_fullscreen ? 0 : WINDOW_DECORATION_WIDTH; +} + +int sdl_window_info::wnd_extra_height() +{ + return m_fullscreen ? 0 : WINDOW_DECORATION_HEIGHT; +} + //============================================================ // constrain_to_aspect_ratio // (window thread) //============================================================ -void sdl_window_info::constrain_to_aspect_ratio(int *window_width, int *window_height, int adjustment) +osd_rect sdl_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int adjustment) { - INT32 extrawidth = 0; - INT32 extraheight = 0; + 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; // get the pixel aspect ratio for the target monitor pixel_aspect = m_monitor->aspect(); // determine the proposed width/height - propwidth = *window_width - extrawidth; - propheight = *window_height - extraheight; + 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 @@ -1431,19 +1433,21 @@ void sdl_window_info::constrain_to_aspect_ratio(int *window_width, int *window_h propheight = MAX(propheight, minheight); // clamp against the maximum (fit on one screen for full screen mode) - maxwidth = m_monitor->position_size().w - extrawidth; - maxheight = m_monitor->position_size().h - extraheight; - if (this->m_fullscreen) + if (m_fullscreen) { - // nothing + maxwidth = m_monitor->position_size().width() - extrawidth; + maxheight = m_monitor->position_size().height() - extraheight; } else { + maxwidth = m_monitor->position_size().width() - extrawidth; + maxheight = m_monitor->position_size().height() - extraheight; + // further clamp to the maximum width/height in the window - if (this->m_win_config.width != 0) - maxwidth = MIN(maxwidth, this->m_win_config.width + extrawidth); - if (this->m_win_config.height != 0) - maxheight = MIN(maxheight, this->m_win_config.height + extraheight); + 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 @@ -1453,9 +1457,38 @@ void sdl_window_info::constrain_to_aspect_ratio(int *window_width, int *window_h // compute the visible area based on the proposed rectangle m_target->compute_visible_area(propwidth, propheight, pixel_aspect, m_target->orientation(), viswidth, visheight); - *window_width = viswidth; - *window_height = 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(), rect.height() + adjheight); + break; + + case WMSZ_LEFT: + case WMSZ_TOPLEFT: + case WMSZ_TOP: + ret = rect.move_by(-adjwidth, -adjheight); + break; + + case WMSZ_TOPRIGHT: + ret = rect.move_by(0, -adjheight).resize(rect.width() + adjwidth, rect.height()); + break; } + return ret; +} + //============================================================ @@ -1463,12 +1496,12 @@ void sdl_window_info::constrain_to_aspect_ratio(int *window_width, int *window_h // (window thread) //============================================================ -void sdl_window_info::get_min_bounds(int *window_width, int *window_height, int constrain) +osd_dim sdl_window_info::get_min_bounds(int constrain) { INT32 minwidth, minheight; // get the minimum target size - this->m_target->compute_minimum_size(minwidth, minheight); + m_target->compute_minimum_size(minwidth, minheight); // expand to our minimum dimensions if (minwidth < MIN_WINDOW_DIM) @@ -1476,73 +1509,74 @@ void sdl_window_info::get_min_bounds(int *window_width, int *window_height, int 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) { - int test1w, test1h; - int test2w, test2h; - // first constrain with no height limit - test1w = minwidth; test1h = 10000; - this->constrain_to_aspect_ratio(&test1w, &test1h, WMSZ_BOTTOMRIGHT); + osd_rect test1(0,0,minwidth,10000); + test1 = constrain_to_aspect_ratio(test1, WMSZ_BOTTOMRIGHT); // then constrain with no width limit - test2w = 10000; test2h = minheight; - this->constrain_to_aspect_ratio(&test2w, &test2h, WMSZ_BOTTOMRIGHT); + osd_rect test2(0,0,10000,minheight); + test2 = constrain_to_aspect_ratio(test2, WMSZ_BOTTOMRIGHT); // pick the larger - if ( test1w > test2w ) + if (test1.width() > test2.width()) { - minwidth = test1w; - minheight = test1h; + minwidth = test1.width(); + minheight = test1.height(); } else { - minwidth = test2w; - minheight = test2h; + minwidth = test2.width(); + minheight = test2.height(); } } - *window_width = minwidth; - *window_height = minheight; + return osd_dim(minwidth, minheight); } + //============================================================ // get_max_bounds // (window thread) //============================================================ -void sdl_window_info::get_max_bounds(int *window_width, int *window_height, int constrain) +osd_dim sdl_window_info::get_max_bounds(int constrain) { - INT32 maxwidth, maxheight; - // compute the maximum client area - maxwidth = m_monitor->position_size().w; - maxheight = m_monitor->position_size().h; + + osd_rect maximum = m_monitor->position_size(); // clamp to the window's max - if (this->m_win_config.width != 0) + int tempw = maximum.width(); + int temph = maximum.height(); + if (m_win_config.width != 0) { - int temp = this->m_win_config.width + WINDOW_DECORATION_WIDTH; - if (temp < maxwidth) - maxwidth = temp; + int temp = m_win_config.width + wnd_extra_width(); + if (temp < maximum.width()) + tempw = temp; } - if (this->m_win_config.height != 0) + if (m_win_config.height != 0) { - int temp = this->m_win_config.height + WINDOW_DECORATION_HEIGHT; - if (temp < maxheight) - maxheight = temp; + 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) - this->constrain_to_aspect_ratio(&maxwidth, &maxheight, WMSZ_BOTTOMRIGHT); - //else + maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT); + else { - maxwidth -= WINDOW_DECORATION_WIDTH; - maxheight -= WINDOW_DECORATION_HEIGHT; - *window_width = maxwidth; - *window_height = maxheight; + maximum = maximum.resize(maximum.width() - wnd_extra_width(), maximum.height() - wnd_extra_height()); } + return maximum.dim(); } diff --git a/src/osd/sdl/window.h b/src/osd/sdl/window.h index 33c06891d49..8b1b87dc2e7 100644 --- a/src/osd/sdl/window.h +++ b/src/osd/sdl/window.h @@ -44,7 +44,8 @@ public: m_resize_height(0), m_last_resize(0), #endif - m_minwidth(0), m_minheight(0), + m_minwidth(0), m_minheight(0), + m_windowed_dim(0,0), m_rendered_event(0), m_target(0), #if (SDLMAME_SDL2) m_sdl_window(NULL), @@ -61,8 +62,7 @@ public: m_fullscreen = !video_config.windowed; m_prescale = video_config.prescale; - m_windowed_width = config->width; - m_windowed_height = config->height; + m_windowed_dim = osd_dim(config->width, config->height); } ~sdl_window_info() @@ -80,12 +80,14 @@ public: void notify_changed(); - void get_size(int &w, int &h) + osd_dim get_size() { #if (SDLMAME_SDL2) + int w=0; int h=0; SDL_GetWindowSize(m_sdl_window, &w, &h); + return osd_dim(w,h); #else - w = m_sdlsurf->w; h = m_sdlsurf->h; + return osd_dim(m_sdlsurf->w, m_sdlsurf->h); #endif } @@ -122,8 +124,7 @@ private: // diverse flags int m_minwidth, m_minheight; - int m_windowed_width; - int m_windowed_height; + osd_dim m_windowed_dim; // rendering info osd_event * m_rendered_event; @@ -150,12 +151,14 @@ private: protected: osd_renderer &renderer() { return *m_renderer; } private: - void constrain_to_aspect_ratio(int *window_width, int *window_height, int adjustment); - void update_cursor_state(); - void pick_best_mode(int *fswidth, int *fsheight); + int wnd_extra_width(); + int wnd_extra_height(); void set_starting_view(running_machine &machine, int index, const char *defview, const char *view); - void get_min_bounds(int *window_width, int *window_height, int constrain); - void get_max_bounds(int *window_width, int *window_height, int constrain); + osd_rect constrain_to_aspect_ratio(const osd_rect &rect, int adjustment); + osd_dim get_min_bounds(int constrain); + osd_dim get_max_bounds(int constrain); + void update_cursor_state(); + osd_dim pick_best_mode(); void set_fullscreen(int afullscreen) { m_fullscreen = afullscreen; } // Pointer to machine diff --git a/src/osd/windows/drawdd.c b/src/osd/windows/drawdd.c index f56ffd4b989..0c1965a56df 100644 --- a/src/osd/windows/drawdd.c +++ b/src/osd/windows/drawdd.c @@ -964,11 +964,11 @@ void renderer_dd::blit_to_primary(int srcwidth, int srcheight) ClientToScreen(window().m_hwnd, &((LPPOINT)&outer)[1]); // adjust to be relative to the monitor - RECT pos = monitor->position_size(); - outer.left -= pos.left; - outer.right -= pos.left; - outer.top -= pos.top; - outer.bottom -= pos.top; + osd_rect pos = monitor->position_size(); + outer.left -= pos.left(); + outer.right -= pos.left(); + outer.top -= pos.top(); + outer.bottom -= pos.top(); } // compute outer rect -- full screen version diff --git a/src/osd/windows/video.h b/src/osd/windows/video.h index f230bb203f2..44bca90b4e0 100644 --- a/src/osd/windows/video.h +++ b/src/osd/windows/video.h @@ -35,6 +35,56 @@ enum { // TYPE DEFINITIONS //============================================================ +class osd_dim +{ +public: + osd_dim(const int &w, const int &h) + : m_w(w), m_h(h) + { + } + int width() const { return m_w; } + int height() const { return m_h; } + +private: + int m_w; + int m_h; +}; + +class osd_rect +{ +public: + osd_rect(const int x, const int y, const int &w, const int &h) + : m_x(x), m_y(y), m_d(w,h) + { + } + osd_rect(const int x, const int y, const osd_dim &d) + : m_x(x), m_y(y), m_d(d) + { + } + int top() const { return m_y; } + int left() const { return m_x; } + int width() const { return m_d.width(); } + int height() const { return m_d.height(); } + + osd_dim dim() const { return m_d; } + + int bottom() const { return m_y + m_d.height(); } + int right() const { return m_x + m_d.width(); } + + osd_rect move_by(int dx, int dy) const { return osd_rect(m_x + dx, m_y + dy, m_d); } + osd_rect resize(int w, int h) const { return osd_rect(m_x, m_y, w, h); } + +private: + int m_x; + int m_y; + osd_dim m_d; +}; + +inline osd_rect RECT_to_osd_rect(const RECT &r) +{ + return osd_rect(r.left, r.top, r.right - r.left, r.bottom - r.top); +} + class win_monitor_info { public: @@ -44,8 +94,9 @@ public: void refresh(); const HMONITOR handle() { return m_handle; } - const RECT &position_size() { refresh(); return m_info.rcMonitor; } - const RECT &usuable_position_size() { refresh(); return m_info.rcWork; } + // position_size is used only by draw_dd renderer + const osd_rect position_size() { refresh(); return RECT_to_osd_rect(m_info.rcMonitor); } + const osd_rect usuable_position_size() { refresh(); return RECT_to_osd_rect(m_info.rcWork); } bool is_primary() { return (m_info.dwFlags & MONITORINFOF_PRIMARY) != 0; } const char *devicename() { refresh(); return (m_name != NULL) ? m_name : "UNKNOWN"; } diff --git a/src/osd/windows/window.c b/src/osd/windows/window.c index 16a22069191..f5875f8d583 100644 --- a/src/osd/windows/window.c +++ b/src/osd/windows/window.c @@ -831,7 +831,7 @@ void win_window_info::update() // (window thread) //============================================================ -win_monitor_info *win_window_info::winwindow_video_window_monitor(const RECT *proposed) +win_monitor_info *win_window_info::winwindow_video_window_monitor(const osd_rect *proposed) { win_monitor_info *monitor; @@ -839,7 +839,14 @@ win_monitor_info *win_window_info::winwindow_video_window_monitor(const RECT *pr if (!m_fullscreen) { if (proposed != NULL) - monitor = winvideo_monitor_from_handle(MonitorFromRect(proposed, MONITOR_DEFAULTTONEAREST)); + { + RECT p; + p.top = proposed->top(); + p.left = proposed->left(); + p.bottom = proposed->bottom(); + p.right = proposed->right(); + monitor = winvideo_monitor_from_handle(MonitorFromRect(&p, MONITOR_DEFAULTTONEAREST)); + } else monitor = winvideo_monitor_from_handle(MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTONEAREST)); } @@ -1153,7 +1160,7 @@ unsigned __stdcall win_window_info::thread_entry(void *param) int win_window_info::complete_create() { - RECT monitorbounds, client; + RECT client; int tempwidth, tempheight; HMENU menu = NULL; HDC dc; @@ -1161,7 +1168,7 @@ int win_window_info::complete_create() assert(GetCurrentThreadId() == window_threadid); // get the monitor bounds - monitorbounds = m_monitor->position_size(); + osd_rect monitorbounds = m_monitor->position_size(); // create the window menu if needed if (downcast(machine().options()).menu()) @@ -1176,8 +1183,8 @@ int win_window_info::complete_create() "MAME", m_title, m_fullscreen ? FULLSCREEN_STYLE : WINDOW_STYLE, - monitorbounds.left + 20, monitorbounds.top + 20, - monitorbounds.left + 100, monitorbounds.top + 100, + monitorbounds.left() + 20, monitorbounds.top() + 20, + monitorbounds.left() + 100, monitorbounds.top() + 100, NULL,//(win_window_list != NULL) ? win_window_list->m_hwnd : NULL, menu, GetModuleHandle(NULL), @@ -1198,9 +1205,9 @@ int win_window_info::complete_create() // adjust the window position to the initial width/height tempwidth = (m_win_config.width != 0) ? m_win_config.width : 640; tempheight = (m_win_config.height != 0) ? m_win_config.height : 480; - SetWindowPos(m_hwnd, NULL, monitorbounds.left + 20, monitorbounds.top + 20, - monitorbounds.left + tempwidth + wnd_extra_width(), - monitorbounds.top + tempheight + wnd_extra_height(), + SetWindowPos(m_hwnd, NULL, monitorbounds.left() + 20, monitorbounds.top() + 20, + monitorbounds.left() + tempwidth + wnd_extra_width(), + monitorbounds.top() + tempheight + wnd_extra_height(), SWP_NOZORDER); // maximum or minimize as appropriate @@ -1346,7 +1353,13 @@ LRESULT CALLBACK win_window_info::video_window_proc(HWND wnd, UINT message, WPAR { RECT *rect = (RECT *)lparam; if (video_config.keepaspect && !(GetAsyncKeyState(VK_CONTROL) & 0x8000)) - window->constrain_to_aspect_ratio(rect, wparam); + { + osd_rect r = window->constrain_to_aspect_ratio(RECT_to_osd_rect(*rect), wparam); + rect->top = r.top(); + rect->left = r.left(); + rect->bottom = r.bottom(); + rect->right = r.right(); + } InvalidateRect(wnd, NULL, FALSE); break; } @@ -1500,9 +1513,9 @@ void win_window_info::draw_video_contents(HDC dc, int update) // (window thread) //============================================================ -void win_window_info::constrain_to_aspect_ratio(RECT *rect, int adjustment) +osd_rect win_window_info::constrain_to_aspect_ratio(const osd_rect &rect, int adjustment) { - win_monitor_info *monitor = winwindow_video_window_monitor(rect); + win_monitor_info *monitor = winwindow_video_window_monitor(&rect); INT32 extrawidth = wnd_extra_width(); INT32 extraheight = wnd_extra_height(); INT32 propwidth, propheight; @@ -1518,8 +1531,8 @@ void win_window_info::constrain_to_aspect_ratio(RECT *rect, int adjustment) pixel_aspect = monitor->aspect(); // determine the proposed width/height - propwidth = rect_width(rect) - extrawidth; - propheight = rect_height(rect) - extraheight; + 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 @@ -1554,13 +1567,13 @@ void win_window_info::constrain_to_aspect_ratio(RECT *rect, int adjustment) // clamp against the maximum (fit on one screen for full screen mode) if (m_fullscreen) { - maxwidth = rect_width(&monitor->position_size()) - extrawidth; - maxheight = rect_height(&monitor->position_size()) - extraheight; + maxwidth = monitor->position_size().width() - extrawidth; + maxheight = monitor->position_size().height() - extraheight; } else { - maxwidth = rect_width(&monitor->usuable_position_size()) - extrawidth; - maxheight = rect_height(&monitor->usuable_position_size()) - extraheight; + 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) @@ -1577,36 +1590,35 @@ void win_window_info::constrain_to_aspect_ratio(RECT *rect, int adjustment) 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(rect); - adjheight = (visheight + extraheight) - rect_height(rect); + 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: - rect->right += adjwidth; - rect->bottom += adjheight; + ret = rect.resize(rect.width() + adjwidth, rect.height() + adjheight); break; case WMSZ_BOTTOMLEFT: - rect->left -= adjwidth; - rect->bottom += adjheight; + ret = rect.move_by(-adjwidth, 0).resize(rect.width(), rect.height() + adjheight); break; case WMSZ_LEFT: case WMSZ_TOPLEFT: case WMSZ_TOP: - rect->left -= adjwidth; - rect->top -= adjheight; + ret = rect.move_by(-adjwidth, -adjheight); break; case WMSZ_TOPRIGHT: - rect->right += adjwidth; - rect->top -= adjheight; + ret = rect.move_by(0, -adjheight).resize(rect.width() + adjwidth, rect.height()); break; } + return ret; } @@ -1616,7 +1628,7 @@ void win_window_info::constrain_to_aspect_ratio(RECT *rect, int adjustment) // (window thread) //============================================================ -void win_window_info::get_min_bounds(RECT *bounds, int constrain) +osd_dim win_window_info::get_min_bounds(int constrain) { INT32 minwidth, minheight; @@ -1638,39 +1650,28 @@ void win_window_info::get_min_bounds(RECT *bounds, int constrain) // 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(&test1, WMSZ_BOTTOMRIGHT); + osd_rect test1(0,0,minwidth,10000); + test1 = constrain_to_aspect_ratio(test1, WMSZ_BOTTOMRIGHT); // then constrain with no width limit - test2.top = test2.left = 0; - test2.right = 10000; - test2.bottom = minheight; - constrain_to_aspect_ratio(&test2, WMSZ_BOTTOMRIGHT); + osd_rect test2(0,0,10000,minheight); + test2 = constrain_to_aspect_ratio(test2, WMSZ_BOTTOMRIGHT); // pick the larger - if (rect_width(&test1) > rect_width(&test2)) + if (test1.width() > test2.width()) { - minwidth = rect_width(&test1); - minheight = rect_height(&test1); + minwidth = test1.width(); + minheight = test1.height(); } else { - minwidth = rect_width(&test2); - minheight = rect_height(&test2); + minwidth = test2.width(); + minheight = test2.height(); } } - // get the window rect - GetWindowRect(m_hwnd, bounds); - - // now adjust - bounds->right = bounds->left + minwidth; - bounds->bottom = bounds->top + minheight; + return osd_dim(minwidth, minheight); } @@ -1680,45 +1681,40 @@ void win_window_info::get_min_bounds(RECT *bounds, int constrain) // (window thread) //============================================================ -void win_window_info::get_max_bounds(RECT *bounds, int constrain) +osd_dim win_window_info::get_max_bounds(int constrain) { - RECT maximum; - assert(GetCurrentThreadId() == window_threadid); // compute the maximum client area m_monitor->refresh(); - maximum = m_monitor->usuable_position_size(); + 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 < rect_width(&maximum)) - maximum.right = maximum.left + temp; + if (temp < maximum.width()) + tempw = temp; } if (m_win_config.height != 0) { int temp = m_win_config.height + wnd_extra_height(); - if (temp < rect_height(&maximum)) - maximum.bottom = maximum.top + temp; + if (temp < maximum.height()) + temph = temp; } + maximum = maximum.resize(tempw, temph); + // constrain to fit if (constrain) - constrain_to_aspect_ratio(&maximum, WMSZ_BOTTOMRIGHT); + maximum = constrain_to_aspect_ratio(maximum, WMSZ_BOTTOMRIGHT); else { - maximum.right -= wnd_extra_width(); - maximum.bottom -= wnd_extra_height(); + maximum = maximum.resize(maximum.width() - wnd_extra_width(), maximum.height() - wnd_extra_height()); } - - // center within the work area - RECT work = m_monitor->usuable_position_size(); - bounds->left = work.left + (rect_width(&work) - rect_width(&maximum)) / 2; - bounds->top = work.top + (rect_height(&work) - rect_height(&maximum)) / 2; - bounds->right = bounds->left + rect_width(&maximum); - bounds->bottom = bounds->top + rect_height(&maximum); + return maximum.dim(); } @@ -1734,18 +1730,18 @@ void win_window_info::update_minmax_state() if (!m_fullscreen) { - RECT bounds, minbounds, maxbounds; + RECT bounds; // compare the maximum bounds versus the current bounds - get_min_bounds(&minbounds, video_config.keepaspect); - get_max_bounds(&maxbounds, video_config.keepaspect); + osd_dim minbounds = get_min_bounds(video_config.keepaspect); + osd_dim maxbounds = get_max_bounds(video_config.keepaspect); GetWindowRect(m_hwnd, &bounds); // if either the width or height matches, we were maximized - m_isminimized = (rect_width(&bounds) == rect_width(&minbounds) || - rect_height(&bounds) == rect_height(&minbounds)); - m_ismaximized = (rect_width(&bounds) == rect_width(&maxbounds) || - rect_height(&bounds) == rect_height(&maxbounds)); + m_isminimized = (rect_width(&bounds) == minbounds.width()) || + (rect_height(&bounds) == minbounds.height()); + m_ismaximized = (rect_width(&bounds) == maxbounds.width()) || + (rect_height(&bounds) == maxbounds.height()); } else { @@ -1763,12 +1759,18 @@ void win_window_info::update_minmax_state() void win_window_info::minimize_window() { - RECT newsize; - assert(GetCurrentThreadId() == window_threadid); - get_min_bounds(&newsize, video_config.keepaspect); - SetWindowPos(m_hwnd, NULL, newsize.left, newsize.top, rect_width(&newsize), rect_height(&newsize), SWP_NOZORDER); + osd_dim newsize = get_min_bounds(video_config.keepaspect); + + // get the window rect + RECT bounds; + GetWindowRect(m_hwnd, &bounds); + + osd_rect newrect(bounds.left, bounds.top, newsize ); + + + SetWindowPos(m_hwnd, NULL, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER); } @@ -1780,12 +1782,17 @@ void win_window_info::minimize_window() void win_window_info::maximize_window() { - RECT newsize; - assert(GetCurrentThreadId() == window_threadid); - get_max_bounds(&newsize, video_config.keepaspect); - SetWindowPos(m_hwnd, NULL, newsize.left, newsize.top, rect_width(&newsize), rect_height(&newsize), SWP_NOZORDER); + osd_dim newsize = get_max_bounds(video_config.keepaspect); + + // center within the work area + osd_rect work = m_monitor->usuable_position_size(); + osd_rect newrect = osd_rect(work.left() + (work.width() - newsize.width()) / 2, + work.top() + (work.height() - newsize.height()) / 2, + newsize); + + SetWindowPos(m_hwnd, NULL, newrect.left(), newrect.top(), newrect.width(), newrect.height(), SWP_NOZORDER); } @@ -1797,20 +1804,20 @@ void win_window_info::maximize_window() void win_window_info::adjust_window_position_after_major_change() { - RECT oldrect, newrect; + RECT oldrect; assert(GetCurrentThreadId() == window_threadid); // get the current size GetWindowRect(m_hwnd, &oldrect); + osd_rect newrect = RECT_to_osd_rect(oldrect); // adjust the window size so the client area is what we want if (!m_fullscreen) { // constrain the existing size to the aspect ratio - newrect = oldrect; if (video_config.keepaspect) - constrain_to_aspect_ratio(&newrect, WMSZ_BOTTOMRIGHT); + newrect = constrain_to_aspect_ratio(newrect, WMSZ_BOTTOMRIGHT); } // in full screen, make sure it covers the primary display @@ -1821,17 +1828,17 @@ void win_window_info::adjust_window_position_after_major_change() } // adjust the position if different - if (oldrect.left != newrect.left || oldrect.top != newrect.top || - oldrect.right != newrect.right || oldrect.bottom != newrect.bottom) + if (oldrect.left != newrect.left() || oldrect.top != newrect.top() || + oldrect.right != newrect.right() || oldrect.bottom != newrect.bottom()) SetWindowPos(m_hwnd, m_fullscreen ? HWND_TOPMOST : HWND_TOP, - newrect.left, newrect.top, - rect_width(&newrect), rect_height(&newrect), 0); + newrect.left(), newrect.top(), + newrect.width(), newrect.height(), 0); // take note of physical window size (used for lightgun coordinate calculation) if (this == win_window_list) { - win_physical_width = rect_width(&newrect); - win_physical_height = rect_height(&newrect); + win_physical_width = newrect.width(); + win_physical_height = newrect.height(); logerror("Physical width %d, height %d\n",win_physical_width,win_physical_height); } } diff --git a/src/osd/windows/window.h b/src/osd/windows/window.h index 6a32a8e4167..7b60c953bba 100644 --- a/src/osd/windows/window.h +++ b/src/osd/windows/window.h @@ -46,7 +46,7 @@ public: void update(); - win_monitor_info *winwindow_video_window_monitor(const RECT *proposed); + win_monitor_info *winwindow_video_window_monitor(const osd_rect *proposed); bool win_has_menu() { @@ -109,13 +109,13 @@ public: private: void draw_video_contents(HDC dc, int update); + int complete_create(); void set_starting_view(int index, const char *view); int wnd_extra_width(); int wnd_extra_height(); - int complete_create(); - void constrain_to_aspect_ratio(RECT *rect, int adjustment); - void get_min_bounds(RECT *bounds, int constrain); - void get_max_bounds(RECT *bounds, int constrain); + osd_rect constrain_to_aspect_ratio(const osd_rect &rect, int adjustment); + osd_dim get_min_bounds(int constrain); + osd_dim get_max_bounds(int constrain); void update_minmax_state(); void minimize_window(); void maximize_window();