render: improve behaviour in general for systems with two screens (sorry about occasional extra warning messages, it's unavoidable)

This commit is contained in:
Vas Crabb 2018-07-20 02:38:09 +10:00
parent fb0e547884
commit f432c4475a
6 changed files with 119 additions and 235 deletions

View File

@ -1,29 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<mamelayout version="2"> <mamelayout version="2">
<view name="Screen 0 Standard (4:3)">
<screen index="0">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 1 Standard (4:3)">
<screen index="1">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 0 Pixel Aspect (~scr0nativexaspect~:~scr0nativeyaspect~)">
<screen index="0">
<bounds left="0" top="0" right="~scr0width~" bottom="~scr0height~" />
</screen>
</view>
<view name="Screen 1 Pixel Aspect (~scr1nativexaspect~:~scr1nativeyaspect~)">
<screen index="1">
<bounds left="0" top="0" right="~scr1width~" bottom="~scr1height~" />
</screen>
</view>
<view name="Dual Over-Under"> <view name="Dual Over-Under">
<screen index="0"> <screen index="0">
<bounds x="0" y="-3.03" width="4" height="3" /> <bounds x="0" y="-3.03" width="4" height="3" />

View File

@ -1,29 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<mamelayout version="2"> <mamelayout version="2">
<view name="Screen 0 Standard (4:3)">
<screen index="0">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 1 Standard (4:3)">
<screen index="1">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 0 Pixel Aspect (~scr0nativexaspect~:~scr0nativeyaspect~)">
<screen index="0">
<bounds left="0" top="0" right="~scr0width~" bottom="~scr0height~" />
</screen>
</view>
<view name="Screen 1 Pixel Aspect (~scr1nativexaspect~:~scr1nativeyaspect~)">
<screen index="1">
<bounds left="0" top="0" right="~scr1width~" bottom="~scr1height~" />
</screen>
</view>
<view name="Dual Side-by-Side"> <view name="Dual Side-by-Side">
<screen index="0"> <screen index="0">
<bounds x="0" y="0" width="4" height="3" /> <bounds x="0" y="0" width="4" height="3" />

View File

@ -1,29 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<mamelayout version="2"> <mamelayout version="2">
<view name="Screen 0 Standard (4:3)">
<screen index="0">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 1 Standard (4:3)">
<screen index="1">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 0 Pixel Aspect (~scr0nativexaspect~:~scr0nativeyaspect~)">
<screen index="0">
<bounds left="0" top="0" right="~scr0width~" bottom="~scr0height~" />
</screen>
</view>
<view name="Screen 1 Pixel Aspect (~scr1nativexaspect~:~scr1nativeyaspect~)">
<screen index="1">
<bounds left="0" top="0" right="~scr1width~" bottom="~scr1height~" />
</screen>
</view>
<view name="Dual Under-Over"> <view name="Dual Under-Over">
<screen index="1"> <screen index="1">
<bounds x="0" y="-3.03" width="4" height="3" /> <bounds x="0" y="-3.03" width="4" height="3" />

View File

@ -1,41 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<mamelayout version="2"> <mamelayout version="2">
<view name="Screen 0 Standard (4:3)">
<screen index="0">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 1 Standard (4:3)">
<screen index="1">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 2 Standard (4:3)">
<screen index="2">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 0 Pixel Aspect (~scr0nativexaspect~:~scr0nativeyaspect~)">
<screen index="0">
<bounds left="0" top="0" right="~scr0width~" bottom="~scr0height~" />
</screen>
</view>
<view name="Screen 1 Pixel Aspect (~scr1nativexaspect~:~scr1nativeyaspect~)">
<screen index="1">
<bounds left="0" top="0" right="~scr1width~" bottom="~scr1height~" />
</screen>
</view>
<view name="Screen 2 Pixel Aspect (~scr2nativexaspect~:~scr2nativeyaspect~)">
<screen index="2">
<bounds left="0" top="0" right="~scr2width~" bottom="~scr2height~" />
</screen>
</view>
<view name="Triple Side-by-Side"> <view name="Triple Side-by-Side">
<screen index="0"> <screen index="0">
<bounds x="0" y="0" width="4" height="3" /> <bounds x="0" y="0" width="4" height="3" />

View File

@ -1112,19 +1112,19 @@ int render_target::configured_view(const char *viewname, int targetindex, int nu
{ {
for (view = view_by_index(viewindex = 0); view != nullptr; view = view_by_index(++viewindex)) for (view = view_by_index(viewindex = 0); view != nullptr; view = view_by_index(++viewindex))
{ {
const render_screen_list &viewscreens = view->screens(); render_screen_list const &viewscreens(view->screens());
if (viewscreens.count() == 0)
break;
if (viewscreens.count() >= scrcount) if (viewscreens.count() >= scrcount)
{ {
bool has_screen = false; bool screen_missing(false);
for (screen_device &screen : iter) for (screen_device &screen : iter)
{
if (!viewscreens.contains(screen)) if (!viewscreens.contains(screen))
{ {
has_screen = true; screen_missing = true;
break; break;
} }
if (!has_screen) }
if (!screen_missing)
break; break;
} }
} }
@ -1709,7 +1709,7 @@ void render_target::load_additional_layout_files(const char *basename, bool have
throw emu_fatalerror("Couldn't parse default layout??"); throw emu_fatalerror("Couldn't parse default layout??");
} }
} }
else if (screens >= 3) // generate default layouts for larger numbers of screens else if (screens >= 2) // generate default layouts for larger numbers of screens
{ {
util::xml::file::ptr const root(util::xml::file::create()); util::xml::file::ptr const root(util::xml::file::create());
if (!root) if (!root)
@ -1763,94 +1763,122 @@ void render_target::load_additional_layout_files(const char *basename, bool have
boundsnode->set_attribute("height", util::xml::normalize_string(util::string_format("~scr%1$uheight~", i).c_str())); boundsnode->set_attribute("height", util::xml::normalize_string(util::string_format("~scr%1$uheight~", i).c_str()));
} }
// helper for generating a view since we do this a lot // generate tiled views if the supplied artwork doesn't provide a view of all screens
auto const generate_view = bool need_tiles(screens >= 3);
[&layoutnode, screens, stdwidth, stdheight] (char const *title, auto &&bounds_callback) if (!need_tiles)
{
util::xml::data_node *viewnode = layoutnode->add_child("view", nullptr);
if (!viewnode)
throw emu_fatalerror("Couldn't create XML node??");
viewnode->set_attribute("name", util::xml::normalize_string(title));
for (unsigned i = 0; screens > i; ++i)
{
util::xml::data_node *const screennode(viewnode->add_child("screen", nullptr));
if (!screennode)
throw emu_fatalerror("Couldn't create XML node??");
screennode->set_attribute_int("index", i);
util::xml::data_node *const boundsnode(screennode->add_child("bounds", nullptr));
if (!boundsnode)
throw emu_fatalerror("Couldn't create XML node??");
bounds_callback(*boundsnode, i);
boundsnode->set_attribute_int("width", stdwidth);
boundsnode->set_attribute_int("height", stdheight);
}
};
// generate linear views
generate_view(
"Left-to-Right",
[stdwidth] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_float("x", i * (stdwidth + 0.03f));
boundsnode.set_attribute_int("y", 0);
});
generate_view(
"Left-to-Right (Gapless)",
[stdwidth] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_int("x", i * stdwidth);
boundsnode.set_attribute_int("y", 0);
});
generate_view(
"Top-to-Bottom",
[stdheight] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_int("x", 0);
boundsnode.set_attribute_float("y", i * (stdheight + 0.03f));
});
generate_view(
"Top-to-Bottom (Gapless)",
[stdheight] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_int("x", 0);
boundsnode.set_attribute_int("y", i * stdheight);
});
// generate tiled views
for (unsigned mindim = 2; ((screens + mindim - 1) / mindim) >= mindim; ++mindim)
{ {
unsigned const majdim((screens + mindim - 1) / mindim); need_tiles = true;
unsigned const remainder(screens % majdim); int viewindex(0);
if (!remainder || (((majdim + 1) / 2) <= remainder)) for (layout_view *view = view_by_index(viewindex); need_tiles && view; view = view_by_index(++viewindex))
{ {
generate_view( render_screen_list const &viewscreens(view->screens());
util::string_format("%1$u\xC3\x97%2$u Left-to-Right, Top-to-Bottom", majdim, mindim).c_str(), if (viewscreens.count() >= screens)
[majdim, stdwidth, stdheight] (util::xml::data_node &boundsnode, unsigned i) {
bool screen_missing(false);
for (screen_device &screen : iter)
{
if (!viewscreens.contains(screen))
{ {
boundsnode.set_attribute_float("x", (i % majdim) * (stdwidth + 0.03f)); screen_missing = true;
boundsnode.set_attribute_float("y", (i / majdim) * (stdheight + 0.03f)); break;
}); }
generate_view( }
util::string_format("%1$u\xC3\x97%2$u Left-to-Right, Top-to-Bottom (Gapless)", majdim, mindim).c_str(), if (!screen_missing)
[majdim, stdwidth, stdheight] (util::xml::data_node &boundsnode, unsigned i) need_tiles = false;
}
}
}
if (need_tiles)
{
// helper for generating a view since we do this a lot
auto const generate_view =
[&layoutnode, screens, stdwidth, stdheight] (char const *title, auto &&bounds_callback)
{
util::xml::data_node *viewnode = layoutnode->add_child("view", nullptr);
if (!viewnode)
throw emu_fatalerror("Couldn't create XML node??");
viewnode->set_attribute("name", util::xml::normalize_string(title));
for (unsigned i = 0; screens > i; ++i)
{ {
boundsnode.set_attribute_int("x", (i % majdim) * stdwidth); util::xml::data_node *const screennode(viewnode->add_child("screen", nullptr));
boundsnode.set_attribute_int("y", (i / majdim) * stdheight); if (!screennode)
}); throw emu_fatalerror("Couldn't create XML node??");
generate_view( screennode->set_attribute_int("index", i);
util::string_format("%1$u\xC3\x97%2$u Top-to-Bottom, Left-to-Right", mindim, majdim).c_str(), util::xml::data_node *const boundsnode(screennode->add_child("bounds", nullptr));
[majdim, stdwidth, stdheight] (util::xml::data_node &boundsnode, unsigned i) if (!boundsnode)
{ throw emu_fatalerror("Couldn't create XML node??");
boundsnode.set_attribute_float("x", (i / majdim) * (stdwidth + 0.03f)); bounds_callback(*boundsnode, i);
boundsnode.set_attribute_float("y", (i % majdim) * (stdheight + 0.03f)); boundsnode->set_attribute_int("width", stdwidth);
}); boundsnode->set_attribute_int("height", stdheight);
generate_view( }
util::string_format("%1$u\xC3\x97%2$u Top-to-Bottom, Left-to-Right (Gapless)", mindim, majdim).c_str(), };
[majdim, stdwidth, stdheight] (util::xml::data_node &boundsnode, unsigned i)
{ // generate linear views
boundsnode.set_attribute_int("x", (i / majdim) * stdwidth); generate_view(
boundsnode.set_attribute_int("y", (i % majdim) * stdheight); "Left-to-Right",
}); [stdwidth] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_float("x", i * (stdwidth + 0.03f));
boundsnode.set_attribute_int("y", 0);
});
generate_view(
"Left-to-Right (Gapless)",
[stdwidth] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_int("x", i * stdwidth);
boundsnode.set_attribute_int("y", 0);
});
generate_view(
"Top-to-Bottom",
[stdheight] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_int("x", 0);
boundsnode.set_attribute_float("y", i * (stdheight + 0.03f));
});
generate_view(
"Top-to-Bottom (Gapless)",
[stdheight] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_int("x", 0);
boundsnode.set_attribute_int("y", i * stdheight);
});
// generate tiled views
for (unsigned mindim = 2; ((screens + mindim - 1) / mindim) >= mindim; ++mindim)
{
unsigned const majdim((screens + mindim - 1) / mindim);
unsigned const remainder(screens % majdim);
if (!remainder || (((majdim + 1) / 2) <= remainder))
{
generate_view(
util::string_format("%1$u\xC3\x97%2$u Left-to-Right, Top-to-Bottom", majdim, mindim).c_str(),
[majdim, stdwidth, stdheight] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_float("x", (i % majdim) * (stdwidth + 0.03f));
boundsnode.set_attribute_float("y", (i / majdim) * (stdheight + 0.03f));
});
generate_view(
util::string_format("%1$u\xC3\x97%2$u Left-to-Right, Top-to-Bottom (Gapless)", majdim, mindim).c_str(),
[majdim, stdwidth, stdheight] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_int("x", (i % majdim) * stdwidth);
boundsnode.set_attribute_int("y", (i / majdim) * stdheight);
});
generate_view(
util::string_format("%1$u\xC3\x97%2$u Top-to-Bottom, Left-to-Right", mindim, majdim).c_str(),
[majdim, stdwidth, stdheight] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_float("x", (i / majdim) * (stdwidth + 0.03f));
boundsnode.set_attribute_float("y", (i % majdim) * (stdheight + 0.03f));
});
generate_view(
util::string_format("%1$u\xC3\x97%2$u Top-to-Bottom, Left-to-Right (Gapless)", mindim, majdim).c_str(),
[majdim, stdwidth, stdheight] (util::xml::data_node &boundsnode, unsigned i)
{
boundsnode.set_attribute_int("x", (i / majdim) * stdwidth);
boundsnode.set_attribute_int("y", (i % majdim) * stdheight);
});
}
} }
} }

View File

@ -1,41 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<mamelayout version="2"> <mamelayout version="2">
<view name="Screen 0 Standard (4:3)">
<screen index="0">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 1 Standard (4:3)">
<screen index="1">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 2 Standard (4:3)">
<screen index="2">
<bounds left="0" top="0" right="4" bottom="3" />
</screen>
</view>
<view name="Screen 0 Pixel Aspect (~scr0nativexaspect~:~scr0nativeyaspect~)">
<screen index="0">
<bounds left="0" top="0" right="~scr0width~" bottom="~scr0height~" />
</screen>
</view>
<view name="Screen 1 Pixel Aspect (~scr1nativexaspect~:~scr1nativeyaspect~)">
<screen index="1">
<bounds left="0" top="0" right="~scr1width~" bottom="~scr1height~" />
</screen>
</view>
<view name="Screen 2 Pixel Aspect (~scr2nativexaspect~:~scr2nativeyaspect~)">
<screen index="2">
<bounds left="0" top="0" right="~scr2width~" bottom="~scr2height~" />
</screen>
</view>
<view name="Triple Side-by-Side"> <view name="Triple Side-by-Side">
<screen index="0"> <screen index="0">
<bounds x="0" y="0" width="4" height="3" /> <bounds x="0" y="0" width="4" height="3" />