mame/src/emu/video.h
therealmogminer@gmail.com 1079f45424 Fix -nodebug crash (nw)
2016-06-08 10:11:42 +10:00

211 lines
8.2 KiB
C++

// 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
const int FRAMESKIP_LEVELS = 12;
const int MAX_FRAMESKIP = FRAMESKIP_LEVELS - 2;
#define LCD_FRAMES_PER_SECOND 30
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// forward references
class render_target;
class screen_device;
class avi_file;
// ======================> 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 { return (m_mng_file || m_avi_file); }
// setters
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();
osd_file::error open_next(emu_file &file, const char *extension);
// 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 end_recording(movie_format format);
void add_sound_to_recording(const INT16 *sound, int numsamples);
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
UINT32 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
UINT32 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
UINT32 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
UINT32 m_seconds_to_run; // number of seconds to run before quitting
bool m_auto_frameskip; // flag: TRUE if we're automatically frameskipping
UINT32 m_speed; // overall speed (*1000)
// frameskipping
UINT8 m_empty_skip_count; // number of empty frames we have skipped
UINT8 m_frameskip_level; // current frameskip level
UINT8 m_frameskip_counter; // counter that counts through the frameskip steps
INT8 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?
INT32 m_snap_width; // width of snapshots (0 == auto)
INT32 m_snap_height; // height of snapshots (0 == auto)
// movie recording - MNG
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
UINT32 m_mng_frame; // current movie frame number
// movie recording - AVI
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
UINT32 m_avi_frame; // current movie frame number
// movie recording - dummy
bool m_dummy_recording; // indicates if snapshot should be created of every frame
static const UINT8 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