summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/emu/debug/dvstate.cpp2
-rw-r--r--src/emu/layout/snap.lay50
-rw-r--r--src/emu/render.cpp72
-rw-r--r--src/emu/render.h6
-rw-r--r--src/emu/screen.h2
-rw-r--r--src/emu/video.cpp208
-rw-r--r--src/emu/video.h4
7 files changed, 172 insertions, 172 deletions
diff --git a/src/emu/debug/dvstate.cpp b/src/emu/debug/dvstate.cpp
index 092c6885ca0..e0004f9bb60 100644
--- a/src/emu/debug/dvstate.cpp
+++ b/src/emu/debug/dvstate.cpp
@@ -136,7 +136,7 @@ void debug_view_state::recompute()
}
else if (screen_count > 1)
{
- for (int i = 0; i < screen_count; i++, iter++)
+ for (int i = 0; (i < screen_count) && (i < 8); i++, iter++)
{
m_state_list.emplace_back(REG_BEAMX_S0 - i, string_format("beamx%d", i).c_str(), 4);
m_state_list.emplace_back(REG_BEAMY_S0 - i, string_format("beamy%d", i).c_str(), 4);
diff --git a/src/emu/layout/snap.lay b/src/emu/layout/snap.lay
deleted file mode 100644
index 76dfb93d60c..00000000000
--- a/src/emu/layout/snap.lay
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0"?>
-<mamelayout version="2">
- <view name="s0">
- <screen index="0">
- <bounds left="0" top="0" right="1" bottom="1" />
- </screen>
- </view>
-
- <view name="s1">
- <screen index="1">
- <bounds left="0" top="0" right="1" bottom="1" />
- </screen>
- </view>
-
- <view name="s2">
- <screen index="2">
- <bounds left="0" top="0" right="1" bottom="1" />
- </screen>
- </view>
-
- <view name="s3">
- <screen index="3">
- <bounds left="0" top="0" right="1" bottom="1" />
- </screen>
- </view>
-
- <view name="s4">
- <screen index="4">
- <bounds left="0" top="0" right="1" bottom="1" />
- </screen>
- </view>
-
- <view name="s5">
- <screen index="5">
- <bounds left="0" top="0" right="1" bottom="1" />
- </screen>
- </view>
-
- <view name="s6">
- <screen index="6">
- <bounds left="0" top="0" right="1" bottom="1" />
- </screen>
- </view>
-
- <view name="s7">
- <screen index="7">
- <bounds left="0" top="0" right="1" bottom="1" />
- </screen>
- </view>
-</mamelayout>
diff --git a/src/emu/render.cpp b/src/emu/render.cpp
index 318ff1c384f..d33590731e8 100644
--- a/src/emu/render.cpp
+++ b/src/emu/render.cpp
@@ -906,21 +906,31 @@ render_container::user_settings::user_settings()
//-------------------------------------------------
render_target::render_target(render_manager &manager, const internal_layout *layoutfile, u32 flags)
- : m_next(nullptr),
- m_manager(manager),
- m_curview(nullptr),
- m_flags(flags),
- m_listindex(0),
- m_width(640),
- m_height(480),
- m_pixel_aspect(0.0f),
- m_max_refresh(0),
- m_orientation(0),
- m_base_view(nullptr),
- m_base_orientation(ROT0),
- m_maxtexwidth(65536),
- m_maxtexheight(65536),
- m_transform_container(true)
+ : render_target(manager, layoutfile, flags, CONSTRUCTOR_IMPL)
+{
+}
+
+render_target::render_target(render_manager &manager, util::xml::data_node const &layout, u32 flags)
+ : render_target(manager, layout, flags, CONSTRUCTOR_IMPL)
+{
+}
+
+template <typename T> render_target::render_target(render_manager &manager, T &&layout, u32 flags, constructor_impl_t)
+ : m_next(nullptr)
+ , m_manager(manager)
+ , m_curview(nullptr)
+ , m_flags(flags)
+ , m_listindex(0)
+ , m_width(640)
+ , m_height(480)
+ , m_pixel_aspect(0.0f)
+ , m_max_refresh(0)
+ , m_orientation(0)
+ , m_base_view(nullptr)
+ , m_base_orientation(ROT0)
+ , m_maxtexwidth(65536)
+ , m_maxtexheight(65536)
+ , m_transform_container(true)
{
// determine the base layer configuration based on options
m_base_layerconfig.set_backdrops_enabled(manager.machine().options().use_backdrops());
@@ -967,7 +977,7 @@ render_target::render_target(render_manager &manager, const internal_layout *lay
m_layerconfig = m_base_layerconfig;
// load the layout files
- load_layout_files(layoutfile, flags & RENDER_CREATE_SINGLE_FILE);
+ load_layout_files(std::forward<T>(layout), flags & RENDER_CREATE_SINGLE_FILE);
// set the current view to the first one
set_view(0);
@@ -1574,9 +1584,7 @@ void render_target::update_layer_config()
void render_target::load_layout_files(const internal_layout *layoutfile, bool singlefile)
{
- bool have_default = false;
bool have_artwork = false;
- bool have_override = false;
// if there's an explicit file, load that first
const char *basename = m_manager.machine().basename();
@@ -1584,8 +1592,27 @@ void render_target::load_layout_files(const internal_layout *layoutfile, bool si
have_artwork |= load_layout_file(basename, layoutfile);
// if we're only loading this file, we know our final result
- if (singlefile)
- return;
+ if (!singlefile)
+ load_additional_layout_files(basename, have_artwork);
+}
+
+void render_target::load_layout_files(util::xml::data_node const &rootnode, bool singlefile)
+{
+ bool have_artwork = false;
+
+ // if there's an explicit file, load that first
+ const char *basename = m_manager.machine().basename();
+ have_artwork |= load_layout_file(basename, rootnode);
+
+ // if we're only loading this file, we know our final result
+ if (!singlefile)
+ load_additional_layout_files(basename, have_artwork);
+}
+
+void render_target::load_additional_layout_files(const char *basename, bool have_artwork)
+{
+ bool have_default = false;
+ bool have_override = false;
// if override_artwork defined, load that and skip artwork other than default
if (m_manager.machine().options().override_artwork())
@@ -2873,6 +2900,11 @@ render_target *render_manager::target_alloc(const internal_layout *layoutfile, u
return &m_targetlist.append(*global_alloc(render_target(*this, layoutfile, flags)));
}
+render_target *render_manager::target_alloc(util::xml::data_node const &layout, u32 flags)
+{
+ return &m_targetlist.append(*global_alloc(render_target(*this, layout, flags)));
+}
+
//-------------------------------------------------
// target_free - free a target
diff --git a/src/emu/render.h b/src/emu/render.h
index e7ac98e8dfb..c68c4e04e23 100644
--- a/src/emu/render.h
+++ b/src/emu/render.h
@@ -934,6 +934,7 @@ class render_target
// construction/destruction
render_target(render_manager &manager, const internal_layout *layoutfile = nullptr, u32 flags = 0);
+ render_target(render_manager &manager, util::xml::data_node const &layout, u32 flags = 0);
~render_target();
public:
@@ -1012,8 +1013,12 @@ public:
private:
// internal helpers
+ enum constructor_impl_t { CONSTRUCTOR_IMPL };
+ template <typename T> render_target(render_manager &manager, T&& layout, u32 flags, constructor_impl_t);
void update_layer_config();
void load_layout_files(const internal_layout *layoutfile, bool singlefile);
+ void load_layout_files(util::xml::data_node const &rootnode, bool singlefile);
+ void load_additional_layout_files(const char *basename, bool have_artwork);
bool load_layout_file(const char *dirname, const char *filename);
bool load_layout_file(const char *dirname, const internal_layout *layout_data);
bool load_layout_file(const char *dirname, util::xml::data_node const &rootnode);
@@ -1095,6 +1100,7 @@ public:
// targets
render_target *target_alloc(const internal_layout *layoutfile = nullptr, u32 flags = 0);
+ render_target *target_alloc(util::xml::data_node const &layout, u32 flags = 0);
void target_free(render_target *target);
const simple_list<render_target> &targets() const { return m_targetlist; }
render_target *first_target() const { return m_targetlist.first(); }
diff --git a/src/emu/screen.h b/src/emu/screen.h
index 1ccda1f6eb0..e3c74cf2faf 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -43,8 +43,6 @@ enum texture_format
// screen_update callback flags
constexpr u32 UPDATE_HAS_NOT_CHANGED = 0x0001; // the video has not changed
-constexpr u32 MAX_NUM_SCREENS = 9;
-
/*!
@defgroup flags for video_attributes
@{
diff --git a/src/emu/video.cpp b/src/emu/video.cpp
index 6cc6af39454..434e51be969 100644
--- a/src/emu/video.cpp
+++ b/src/emu/video.cpp
@@ -10,18 +10,19 @@
#include "emu.h"
#include "emuopts.h"
-#include "png.h"
#include "debugger.h"
#include "ui/uimain.h"
-#include "aviio.h"
#include "crsshair.h"
#include "rendersw.hxx"
#include "output.h"
-#include "snap.lh"
+#include "aviio.h"
+#include "png.h"
+#include "xmlfile.h"
#include "osdepend.h"
+
//**************************************************************************
// DEBUGGING
//**************************************************************************
@@ -70,42 +71,41 @@ static void video_notifier_callback(const char *outname, s32 value, void *param)
//-------------------------------------------------
video_manager::video_manager(running_machine &machine)
- : m_machine(machine),
- m_screenless_frame_timer(nullptr),
- m_output_changed(false),
- m_throttle_last_ticks(0),
- m_throttle_realtime(attotime::zero),
- m_throttle_emutime(attotime::zero),
- m_throttle_history(0),
- m_speed_last_realtime(0),
- m_speed_last_emutime(attotime::zero),
- m_speed_percent(1.0),
- m_overall_real_seconds(0),
- m_overall_real_ticks(0),
- m_overall_emutime(attotime::zero),
- m_overall_valid_counter(0),
- m_throttled(machine.options().throttle()),
- m_throttle_rate(1.0f),
- m_fastforward(false),
- m_seconds_to_run(machine.options().seconds_to_run()),
- m_auto_frameskip(machine.options().auto_frameskip()),
- m_speed(original_speed_setting()),
- m_empty_skip_count(0),
- m_frameskip_level(machine.options().frameskip()),
- m_frameskip_counter(0),
- m_frameskip_adjust(0),
- m_skipping_this_frame(false),
- m_average_oversleep(0),
- m_snap_target(nullptr),
- m_snap_native(true),
- m_snap_width(0),
- m_snap_height(0),
- m_timecode_enabled(false),
- m_timecode_write(false),
- m_timecode_text(""),
- m_timecode_start(attotime::zero),
- m_timecode_total(attotime::zero)
-
+ : m_machine(machine)
+ , m_screenless_frame_timer(nullptr)
+ , m_output_changed(false)
+ , m_throttle_last_ticks(0)
+ , m_throttle_realtime(attotime::zero)
+ , m_throttle_emutime(attotime::zero)
+ , m_throttle_history(0)
+ , m_speed_last_realtime(0)
+ , m_speed_last_emutime(attotime::zero)
+ , m_speed_percent(1.0)
+ , m_overall_real_seconds(0)
+ , m_overall_real_ticks(0)
+ , m_overall_emutime(attotime::zero)
+ , m_overall_valid_counter(0)
+ , m_throttled(machine.options().throttle())
+ , m_throttle_rate(1.0f)
+ , m_fastforward(false)
+ , m_seconds_to_run(machine.options().seconds_to_run())
+ , m_auto_frameskip(machine.options().auto_frameskip())
+ , m_speed(original_speed_setting())
+ , m_empty_skip_count(0)
+ , m_frameskip_level(machine.options().frameskip())
+ , m_frameskip_counter(0)
+ , m_frameskip_adjust(0)
+ , m_skipping_this_frame(false)
+ , m_average_oversleep(0)
+ , m_snap_target(nullptr)
+ , m_snap_native(true)
+ , m_snap_width(0)
+ , m_snap_height(0)
+ , m_timecode_enabled(false)
+ , m_timecode_write(false)
+ , m_timecode_text("")
+ , m_timecode_start(attotime::zero)
+ , m_timecode_total(attotime::zero)
{
// request a callback upon exiting
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&video_manager::exit, this));
@@ -114,7 +114,8 @@ video_manager::video_manager(running_machine &machine)
// extract initial execution state from global configuration settings
update_refresh_speed();
- const bool no_screens = screen_device_iterator(machine.root_device()).count() == 0;
+ const unsigned screen_count(screen_device_iterator(machine.root_device()).count());
+ const bool no_screens(!screen_count);
// create a render target for snapshots
const char *viewname = machine.options().snap_view();
@@ -123,7 +124,34 @@ video_manager::video_manager(running_machine &machine)
if (m_snap_native)
{
// the native target is hard-coded to our internal layout and has all options disabled
- m_snap_target = machine.render().target_alloc(&layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN);
+ util::xml::file::ptr const root(util::xml::file::create());
+ if (!root)
+ throw emu_fatalerror("Couldn't create XML document??");
+ util::xml::data_node *const layoutnode(root->add_child("mamelayout", nullptr));
+ if (!layoutnode)
+ throw emu_fatalerror("Couldn't create XML node??");
+ layoutnode->set_attribute_int("version", 2);
+
+ for (unsigned i = 0; screen_count > i; ++i)
+ {
+ util::xml::data_node *const viewnode(layoutnode->add_child("view", nullptr));
+ if (!viewnode)
+ throw emu_fatalerror("Couldn't create XML node??");
+ viewnode->set_attribute("name", util::xml::normalize_string(util::string_format("s%1$u", i).c_str()));
+ 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??");
+ boundsnode->set_attribute_int("left", 0);
+ boundsnode->set_attribute_int("top", 0);
+ boundsnode->set_attribute_int("right", 1);
+ boundsnode->set_attribute_int("bottom", 1);
+ }
+
+ m_snap_target = machine.render().target_alloc(*root, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN);
m_snap_target->set_backdrops_enabled(false);
m_snap_target->set_overlays_enabled(false);
m_snap_target->set_bezels_enabled(false);
@@ -537,6 +565,8 @@ void video_manager::begin_recording(const char *name, movie_format format)
switch (format)
{
case MF_AVI:
+ if (m_avis.empty())
+ m_avis.resize(count);
if (m_snap_native)
{
for (uint32_t index = 0; index < count; index++, iter++)
@@ -553,6 +583,8 @@ void video_manager::begin_recording(const char *name, movie_format format)
break;
case MF_MNG:
+ if (m_mngs.empty())
+ m_mngs.resize(count);
if (m_snap_native)
{
for (uint32_t index = 0; index < count; index++, iter++)
@@ -564,7 +596,7 @@ void video_manager::begin_recording(const char *name, movie_format format)
else
{
create_snapshot_bitmap(nullptr);
- begin_recording_avi(name, 0, iter.current());
+ begin_recording_mng(name, 0, iter.current());
}
break;
@@ -615,17 +647,11 @@ void video_manager::end_recording_mng(uint32_t index)
void video_manager::add_sound_to_recording(const s16 *sound, int numsamples)
{
- if (m_snap_native)
+ for (uint32_t index = 0; index < m_avis.size(); index++)
{
- const uint32_t count = (uint32_t)screen_device_iterator(machine().root_device()).count();
- for (uint32_t index = 0; index < count; index++)
- {
- add_sound_to_avi_recording(sound, numsamples, index);
- }
- }
- else
- {
- add_sound_to_avi_recording(sound, numsamples, 0);
+ add_sound_to_avi_recording(sound, numsamples, index);
+ if (!m_snap_native)
+ break;
}
}
@@ -660,19 +686,16 @@ void video_manager::add_sound_to_avi_recording(const s16 *sound, int numsamples,
void video_manager::exit()
{
// stop recording any movie
+ for (uint32_t index = 0; index < (std::max)(m_mngs.size(), m_avis.size()); index++)
+ {
+ if (index < m_avis.size())
+ end_recording_avi(index);
- screen_device_iterator device_iterator = screen_device_iterator(machine().root_device());
- screen_device_iterator::auto_iterator iter = device_iterator.begin();
- const uint32_t count = (uint32_t)device_iterator.count();
+ if (index < m_mngs.size())
+ end_recording_mng(index);
- for (uint32_t index = 0; index < count; index++, iter++)
- {
- end_recording_avi(index);
- end_recording_mng(index);
if (!m_snap_native)
- {
break;
- }
}
// free the snapshot target
@@ -709,18 +732,16 @@ void video_manager::screenless_update_callback(void *ptr, int param)
void video_manager::postload()
{
- screen_device_iterator device_iterator = screen_device_iterator(machine().root_device());
- screen_device_iterator::auto_iterator iter = device_iterator.begin();
- const uint32_t count = (uint32_t)device_iterator.count();
-
- for (uint32_t index = 0; index < count; index++, iter++)
+ for (uint32_t index = 0; index < (std::max)(m_mngs.size(), m_avis.size()); index++)
{
- m_avis[index].m_avi_next_frame_time = machine().time();
- m_mngs[index].m_mng_next_frame_time = machine().time();
+ if (index < m_avis.size())
+ m_avis[index].m_avi_next_frame_time = machine().time();
+
+ if (index < m_mngs.size())
+ m_mngs[index].m_mng_next_frame_time = machine().time();
+
if (!m_snap_native)
- {
break;
- }
}
}
@@ -732,22 +753,20 @@ void video_manager::postload()
bool video_manager::is_recording() const
{
- screen_device_iterator device_iterator = screen_device_iterator(machine().root_device());
- screen_device_iterator::auto_iterator iter = device_iterator.begin();
- const uint32_t count = (uint32_t)device_iterator.count();
-
- for (uint32_t index = 0; index < count; index++, iter++)
+ for (mng_info_t const &mng : m_mngs)
{
- if (m_mngs[index].m_mng_file || m_avis[index].m_avi_file)
- {
+ if (mng.m_mng_file)
return true;
- }
- if (!m_snap_native)
- {
+ else if (!m_snap_native)
+ break;
+ }
+ for (avi_info_t const &avi : m_avis)
+ {
+ if (avi.m_avi_file)
+ return true;
+ else if (!m_snap_native)
break;
- }
}
-
return false;
}
@@ -1395,13 +1414,7 @@ osd_file::error video_manager::open_next(emu_file &file, const char *extension,
void video_manager::record_frame()
{
// ignore if nothing to do
- bool any_recording = false;
- for (uint32_t index = 0; index < MAX_NUM_SCREENS && !any_recording; index++)
- {
- if (m_mngs[index].m_mng_file != nullptr || m_avis[index].m_avi_file != nullptr)
- any_recording = true;
- }
- if (!any_recording)
+ if (!is_recording())
return;
// start the profiler and get the current time
@@ -1410,17 +1423,17 @@ void video_manager::record_frame()
screen_device_iterator device_iterator = screen_device_iterator(machine().root_device());
screen_device_iterator::auto_iterator iter = device_iterator.begin();
- const uint32_t count = (uint32_t)device_iterator.count();
- for (uint32_t index = 0; index < count; index++, iter++)
+ for (uint32_t index = 0; index < (std::max)(m_mngs.size(), m_avis.size()); index++, iter++)
{
// create the bitmap
create_snapshot_bitmap(iter.current());
// handle an AVI recording
- avi_info_t &avi_info = m_avis[index];
- if (avi_info.m_avi_file != nullptr)
+ if ((index < m_avis.size()) && m_avis[index].m_avi_file)
{
+ avi_info_t &avi_info = m_avis[index];
+
// loop until we hit the right time
while (avi_info.m_avi_next_frame_time <= curtime)
{
@@ -1428,7 +1441,7 @@ void video_manager::record_frame()
avi_file::error avierr = avi_info.m_avi_file->append_video_frame(m_snap_bitmap);
if (avierr != avi_file::error::NONE)
{
- g_profiler.stop();
+ g_profiler.stop(); // FIXME: double exit if this happens?
end_recording_avi(index);
break;
}
@@ -1440,9 +1453,10 @@ void video_manager::record_frame()
}
// handle a MNG recording
- mng_info_t &mng_info = m_mngs[index];
- if (mng_info.m_mng_file != nullptr)
+ if ((index < m_mngs.size()) && m_mngs[index].m_mng_file)
{
+ mng_info_t &mng_info = m_mngs[index];
+
// loop until we hit the right time
while (mng_info.m_mng_next_frame_time <= curtime)
{
@@ -1463,7 +1477,7 @@ void video_manager::record_frame()
png_error error = mng_capture_frame(*mng_info.m_mng_file, pnginfo, m_snap_bitmap, entries, palette);
if (error != PNGERR_NONE)
{
- g_profiler.stop();
+ g_profiler.stop(); // FIXME: double exit if this happens?
end_recording_mng(index);
break;
}
diff --git a/src/emu/video.h b/src/emu/video.h
index ac8de0064cd..fa9fc6abbe7 100644
--- a/src/emu/video.h
+++ b/src/emu/video.h
@@ -193,7 +193,7 @@ private:
attotime m_mng_next_frame_time; // time of next frame
u32 m_mng_frame; // current movie frame number
};
- mng_info_t m_mngs[9];
+ std::vector<mng_info_t> m_mngs;
// movie recording - AVI
class avi_info_t
@@ -210,7 +210,7 @@ private:
attotime m_avi_next_frame_time; // time of next frame
u32 m_avi_frame; // current movie frame number
};
- avi_info_t m_avis[9];
+ std::vector<avi_info_t> m_avis;
static const bool s_skiptable[FRAMESKIP_LEVELS][FRAMESKIP_LEVELS];