summaryrefslogtreecommitdiffstats
path: root/docs/release/src/emu/video.h
diff options
context:
space:
mode:
Diffstat (limited to 'docs/release/src/emu/video.h')
-rw-r--r--docs/release/src/emu/video.h226
1 files changed, 226 insertions, 0 deletions
diff --git a/docs/release/src/emu/video.h b/docs/release/src/emu/video.h
new file mode 100644
index 00000000000..725107e7db2
--- /dev/null
+++ b/docs/release/src/emu/video.h
@@ -0,0 +1,226 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ video.h
+
+ Core MAME video routines.
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __EMU_H__
+#error Dont include this file directly; include emu.h instead.
+#endif
+
+#ifndef MAME_EMU_VIDEO_H
+#define MAME_EMU_VIDEO_H
+
+#include "aviio.h"
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+// number of levels of frameskipping supported
+constexpr int FRAMESKIP_LEVELS = 12;
+constexpr int MAX_FRAMESKIP = FRAMESKIP_LEVELS - 2;
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> video_manager
+
+class video_manager
+{
+ friend class screen_device;
+
+public:
+ // movie format options
+ enum movie_format
+ {
+ MF_MNG,
+ MF_AVI
+ };
+
+ // construction/destruction
+ video_manager(running_machine &machine);
+
+ // getters
+ running_machine &machine() const { return m_machine; }
+ bool skip_this_frame() const { return m_skipping_this_frame; }
+ int speed_factor() const { return m_speed; }
+ int frameskip() const { return m_auto_frameskip ? -1 : m_frameskip_level; }
+ bool throttled() const { return m_throttled; }
+ float throttle_rate() const { return m_throttle_rate; }
+ bool fastforward() const { return m_fastforward; }
+ bool is_recording() const;
+
+ // setters
+ void set_speed_factor(int speed) { m_speed = speed; } // MESSUI
+ void set_frameskip(int frameskip);
+ void set_throttled(bool throttled = true) { m_throttled = throttled; }
+ void set_throttle_rate(float throttle_rate) { m_throttle_rate = throttle_rate; }
+ void set_fastforward(bool ffwd = true) { m_fastforward = ffwd; }
+ void set_output_changed() { m_output_changed = true; }
+
+ // misc
+ void toggle_throttle();
+ void toggle_record_movie(movie_format format);
+ void toggle_record_mng() { toggle_record_movie(MF_MNG); }
+ void toggle_record_avi() { toggle_record_movie(MF_AVI); }
+ osd_file::error open_next(emu_file &file, const char *extension, uint32_t index = 0);
+
+ // render a frame
+ void frame_update(bool from_debugger = false);
+
+ // current speed helpers
+ std::string speed_text();
+ double speed_percent() const { return m_speed_percent; }
+
+ // snapshots
+ void save_snapshot(screen_device *screen, emu_file &file);
+ void save_active_screen_snapshots();
+ void save_input_timecode();
+
+ // movies
+ void begin_recording(const char *name, movie_format format);
+ void begin_recording_mng(const char *name, uint32_t index, screen_device *screen);
+ void begin_recording_avi(const char *name, uint32_t index, screen_device *screen);
+ void end_recording(movie_format format);
+ void end_recording_mng(uint32_t index);
+ void end_recording_avi(uint32_t index);
+ void add_sound_to_recording(const s16 *sound, int numsamples);
+ void add_sound_to_avi_recording(const s16 *sound, int numsamples, uint32_t index);
+
+ void set_timecode_enabled(bool value) { m_timecode_enabled = value; }
+ bool get_timecode_enabled() { return m_timecode_enabled; }
+ bool get_timecode_write() { return m_timecode_write; }
+ void set_timecode_write(bool value) { m_timecode_write = value; }
+ void set_timecode_text(std::string &str) { m_timecode_text = str; }
+ void set_timecode_start(attotime time) { m_timecode_start = time; }
+ void add_to_total_time(attotime time) { m_timecode_total += time; }
+ std::string &timecode_text(std::string &str);
+ std::string &timecode_total_text(std::string &str);
+
+private:
+ // internal helpers
+ void exit();
+ void screenless_update_callback(void *ptr, int param);
+ void postload();
+
+ // effective value helpers
+ bool effective_autoframeskip() const;
+ int effective_frameskip() const;
+ bool effective_throttle() const;
+
+ // speed and throttling helpers
+ int original_speed_setting() const;
+ bool finish_screen_updates();
+ void update_throttle(attotime emutime);
+ osd_ticks_t throttle_until_ticks(osd_ticks_t target_ticks);
+ void update_frameskip();
+ void update_refresh_speed();
+ void recompute_speed(const attotime &emutime);
+
+ // snapshot/movie helpers
+ void create_snapshot_bitmap(screen_device *screen);
+ void record_frame();
+
+ // internal state
+ running_machine & m_machine; // reference to our machine
+
+ // screenless systems
+ emu_timer * m_screenless_frame_timer; // timer to signal VBLANK start
+ bool m_output_changed; // did an output element change?
+
+ // throttling calculations
+ osd_ticks_t m_throttle_last_ticks; // osd_ticks the last call to throttle
+ attotime m_throttle_realtime; // real time the last call to throttle
+ attotime m_throttle_emutime; // emulated time the last call to throttle
+ u32 m_throttle_history; // history of frames where we were fast enough
+
+ // dynamic speed computation
+ osd_ticks_t m_speed_last_realtime; // real time at the last speed calculation
+ attotime m_speed_last_emutime; // emulated time at the last speed calculation
+ double m_speed_percent; // most recent speed percentage
+
+ // overall speed computation
+ u32 m_overall_real_seconds; // accumulated real seconds at normal speed
+ osd_ticks_t m_overall_real_ticks; // accumulated real ticks at normal speed
+ attotime m_overall_emutime; // accumulated emulated time at normal speed
+ u32 m_overall_valid_counter; // number of consecutive valid time periods
+
+ // configuration
+ bool m_throttled; // flag: true if we're currently throttled
+ float m_throttle_rate; // target rate for throttling
+ bool m_fastforward; // flag: true if we're currently fast-forwarding
+ u32 m_seconds_to_run; // number of seconds to run before quitting
+ bool m_auto_frameskip; // flag: true if we're automatically frameskipping
+ u32 m_speed; // overall speed (*1000)
+
+ // frameskipping
+ u8 m_empty_skip_count; // number of empty frames we have skipped
+ u8 m_frameskip_level; // current frameskip level
+ u8 m_frameskip_counter; // counter that counts through the frameskip steps
+ s8 m_frameskip_adjust;
+ bool m_skipping_this_frame; // flag: true if we are skipping the current frame
+ osd_ticks_t m_average_oversleep; // average number of ticks the OSD oversleeps
+
+ // snapshot stuff
+ render_target * m_snap_target; // screen shapshot target
+ bitmap_rgb32 m_snap_bitmap; // screen snapshot bitmap
+ bool m_snap_native; // are we using native per-screen layouts?
+ s32 m_snap_width; // width of snapshots (0 == auto)
+ s32 m_snap_height; // height of snapshots (0 == auto)
+
+ // movie recording - MNG
+ class mng_info_t
+ {
+ public:
+ mng_info_t()
+ : m_mng_frame_period(attotime::zero)
+ , m_mng_next_frame_time(attotime::zero)
+ , m_mng_frame(0) { }
+
+ std::unique_ptr<emu_file> m_mng_file; // handle to the open movie file
+ attotime m_mng_frame_period; // period of a single movie frame
+ attotime m_mng_next_frame_time; // time of next frame
+ u32 m_mng_frame; // current movie frame number
+ };
+ std::vector<mng_info_t> m_mngs;
+
+ // movie recording - AVI
+ class avi_info_t
+ {
+ public:
+ avi_info_t()
+ : m_avi_file(nullptr)
+ , m_avi_frame_period(attotime::zero)
+ , m_avi_next_frame_time(attotime::zero)
+ , m_avi_frame(0) { }
+
+ avi_file::ptr m_avi_file; // handle to the open movie file
+ attotime m_avi_frame_period; // period of a single movie frame
+ attotime m_avi_next_frame_time; // time of next frame
+ u32 m_avi_frame; // current movie frame number
+ };
+ std::vector<avi_info_t> m_avis;
+
+ static const bool s_skiptable[FRAMESKIP_LEVELS][FRAMESKIP_LEVELS];
+
+ static const attoseconds_t ATTOSECONDS_PER_SPEED_UPDATE = ATTOSECONDS_PER_SECOND / 4;
+ static const int PAUSED_REFRESH_RATE = 30;
+
+ bool m_timecode_enabled; // inp.timecode record enabled
+ bool m_timecode_write; // Show/hide timer at right (partial time)
+ std::string m_timecode_text; // Message for that video part (intro, gameplay, extra)
+ attotime m_timecode_start; // Starting timer for that video part (intro, gameplay, extra)
+ attotime m_timecode_total; // Show/hide timer at left (total elapsed on resulting video preview)
+};
+
+#endif // MAME_EMU_VIDEO_H