Introduced osd_rect and osd_dim to allow for more code alignment. (nw)

This commit is contained in:
couriersud 2015-02-27 00:19:41 +01:00
parent 39eb12210c
commit b77fbed384
11 changed files with 375 additions and 233 deletions

View File

@ -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;

View File

@ -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)
{

View File

@ -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);

View File

@ -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)

View File

@ -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"; }

View File

@ -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();
}

View File

@ -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

View File

@ -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

View File

@ -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"; }

View File

@ -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<windows_options &>(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);
}
}

View File

@ -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();