mirror of
https://github.com/holub/mame
synced 2025-06-06 21:03:47 +03:00
MNG is now written when -mngwrite is used together with -aviwrite [Oliver Stöneberg]
This commit is contained in:
parent
d63e60a4c8
commit
9a49c214e3
159
src/emu/video.c
159
src/emu/video.c
@ -101,10 +101,13 @@ video_manager::video_manager(running_machine &machine)
|
|||||||
m_snap_native(true),
|
m_snap_native(true),
|
||||||
m_snap_width(0),
|
m_snap_width(0),
|
||||||
m_snap_height(0),
|
m_snap_height(0),
|
||||||
m_avifile(NULL),
|
m_mng_frame_period(attotime::zero),
|
||||||
m_movie_frame_period(attotime::zero),
|
m_mng_next_frame_time(attotime::zero),
|
||||||
m_movie_next_frame_time(attotime::zero),
|
m_mng_frame(0),
|
||||||
m_movie_frame(0)
|
m_avi_file(NULL),
|
||||||
|
m_avi_frame_period(attotime::zero),
|
||||||
|
m_avi_next_frame_time(attotime::zero),
|
||||||
|
m_avi_frame(0)
|
||||||
{
|
{
|
||||||
// request a callback upon exiting
|
// request a callback upon exiting
|
||||||
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(video_manager::exit), this));
|
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(video_manager::exit), this));
|
||||||
@ -359,19 +362,19 @@ void video_manager::save_active_screen_snapshots()
|
|||||||
|
|
||||||
void video_manager::begin_recording(const char *name, movie_format format)
|
void video_manager::begin_recording(const char *name, movie_format format)
|
||||||
{
|
{
|
||||||
// stop any existign recording
|
|
||||||
end_recording();
|
|
||||||
|
|
||||||
// create a snapshot bitmap so we know what the target size is
|
// create a snapshot bitmap so we know what the target size is
|
||||||
create_snapshot_bitmap(NULL);
|
create_snapshot_bitmap(NULL);
|
||||||
|
|
||||||
// reset the state
|
|
||||||
m_movie_frame = 0;
|
|
||||||
m_movie_next_frame_time = machine().time();
|
|
||||||
|
|
||||||
// start up an AVI recording
|
// start up an AVI recording
|
||||||
if (format == MF_AVI)
|
if (format == MF_AVI)
|
||||||
{
|
{
|
||||||
|
// stop any existing recording
|
||||||
|
end_recording(format);
|
||||||
|
|
||||||
|
// reset the state
|
||||||
|
m_avi_frame = 0;
|
||||||
|
m_avi_next_frame_time = machine().time();
|
||||||
|
|
||||||
// build up information about this new movie
|
// build up information about this new movie
|
||||||
avi_movie_info info;
|
avi_movie_info info;
|
||||||
info.video_format = 0;
|
info.video_format = 0;
|
||||||
@ -400,9 +403,6 @@ void video_manager::begin_recording(const char *name, movie_format format)
|
|||||||
else
|
else
|
||||||
filerr = open_next(tempfile, "avi");
|
filerr = open_next(tempfile, "avi");
|
||||||
|
|
||||||
// compute the frame time
|
|
||||||
m_movie_frame_period = attotime::from_seconds(1000) / info.video_timescale;
|
|
||||||
|
|
||||||
// if we succeeded, make a copy of the name and create the real file over top
|
// if we succeeded, make a copy of the name and create the real file over top
|
||||||
if (filerr == FILERR_NONE)
|
if (filerr == FILERR_NONE)
|
||||||
fullpath = tempfile.fullpath();
|
fullpath = tempfile.fullpath();
|
||||||
@ -410,39 +410,55 @@ void video_manager::begin_recording(const char *name, movie_format format)
|
|||||||
|
|
||||||
if (filerr == FILERR_NONE)
|
if (filerr == FILERR_NONE)
|
||||||
{
|
{
|
||||||
|
// compute the frame time
|
||||||
|
m_avi_frame_period = attotime::from_seconds(1000) / info.video_timescale;
|
||||||
|
|
||||||
// create the file and free the string
|
// create the file and free the string
|
||||||
avi_error avierr = avi_create(fullpath, &info, &m_avifile);
|
avi_error avierr = avi_create(fullpath, &info, &m_avi_file);
|
||||||
if (avierr != AVIERR_NONE)
|
if (avierr != AVIERR_NONE)
|
||||||
|
{
|
||||||
mame_printf_error("Error creating AVI: %s\n", avi_error_string(avierr));
|
mame_printf_error("Error creating AVI: %s\n", avi_error_string(avierr));
|
||||||
|
return end_recording(format);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// start up a MNG recording
|
// start up a MNG recording
|
||||||
else if (format == MF_MNG)
|
else if (format == MF_MNG)
|
||||||
{
|
{
|
||||||
|
// stop any existing recording
|
||||||
|
end_recording(format);
|
||||||
|
|
||||||
|
// reset the state
|
||||||
|
m_mng_frame = 0;
|
||||||
|
m_mng_next_frame_time = machine().time();
|
||||||
|
|
||||||
// create a new movie file and start recording
|
// create a new movie file and start recording
|
||||||
m_mngfile.reset(global_alloc(emu_file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)));
|
m_mng_file.reset(global_alloc(emu_file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS)));
|
||||||
file_error filerr;
|
file_error filerr;
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
filerr = m_mngfile->open(name);
|
filerr = m_mng_file->open(name);
|
||||||
else
|
else
|
||||||
filerr = open_next(*m_mngfile, "mng");
|
filerr = open_next(*m_mng_file, "mng");
|
||||||
|
|
||||||
if (filerr == FILERR_NONE)
|
if (filerr == FILERR_NONE)
|
||||||
{
|
{
|
||||||
// start the capture
|
// start the capture
|
||||||
int rate = (machine().first_screen() != NULL) ? ATTOSECONDS_TO_HZ(machine().first_screen()->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE;
|
int rate = (machine().first_screen() != NULL) ? ATTOSECONDS_TO_HZ(machine().first_screen()->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE;
|
||||||
png_error pngerr = mng_capture_start(*m_mngfile, m_snap_bitmap, rate);
|
png_error pngerr = mng_capture_start(*m_mng_file, m_snap_bitmap, rate);
|
||||||
if (pngerr != PNGERR_NONE)
|
if (pngerr != PNGERR_NONE)
|
||||||
return end_recording();
|
{
|
||||||
|
mame_printf_error("Error capturing MNG, png_error=%d\n", pngerr);
|
||||||
|
return end_recording(format);
|
||||||
|
}
|
||||||
|
|
||||||
// compute the frame time
|
// compute the frame time
|
||||||
m_movie_frame_period = attotime::from_hz(rate);
|
m_mng_frame_period = attotime::from_hz(rate);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mame_printf_error("Error creating MNG\n");
|
mame_printf_error("Error creating MNG, file_error=%d\n", filerr);
|
||||||
m_mngfile.reset();
|
m_mng_file.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -452,24 +468,32 @@ void video_manager::begin_recording(const char *name, movie_format format)
|
|||||||
// end_recording - stop recording of a movie
|
// end_recording - stop recording of a movie
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void video_manager::end_recording()
|
void video_manager::end_recording(movie_format format)
|
||||||
{
|
{
|
||||||
// close the file if it exists
|
if (format == MF_AVI)
|
||||||
if (m_avifile != NULL)
|
|
||||||
{
|
{
|
||||||
avi_close(m_avifile);
|
// close the file if it exists
|
||||||
m_avifile = NULL;
|
if (m_avi_file != NULL)
|
||||||
|
{
|
||||||
|
avi_close(m_avi_file);
|
||||||
|
m_avi_file = NULL;
|
||||||
|
|
||||||
|
// reset the state
|
||||||
|
m_avi_frame = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (format == MF_MNG)
|
||||||
// close the file if it exists
|
|
||||||
if (m_mngfile != NULL)
|
|
||||||
{
|
{
|
||||||
mng_capture_stop(*m_mngfile);
|
// close the file if it exists
|
||||||
m_mngfile.reset();
|
if (m_mng_file != NULL)
|
||||||
}
|
{
|
||||||
|
mng_capture_stop(*m_mng_file);
|
||||||
|
m_mng_file.reset();
|
||||||
|
|
||||||
// reset the state
|
// reset the state
|
||||||
m_movie_frame = 0;
|
m_mng_frame = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -481,16 +505,16 @@ void video_manager::end_recording()
|
|||||||
void video_manager::add_sound_to_recording(const INT16 *sound, int numsamples)
|
void video_manager::add_sound_to_recording(const INT16 *sound, int numsamples)
|
||||||
{
|
{
|
||||||
// only record if we have a file
|
// only record if we have a file
|
||||||
if (m_avifile != NULL)
|
if (m_avi_file != NULL)
|
||||||
{
|
{
|
||||||
g_profiler.start(PROFILER_MOVIE_REC);
|
g_profiler.start(PROFILER_MOVIE_REC);
|
||||||
|
|
||||||
// write the next frame
|
// write the next frame
|
||||||
avi_error avierr = avi_append_sound_samples(m_avifile, 0, sound + 0, numsamples, 1);
|
avi_error avierr = avi_append_sound_samples(m_avi_file, 0, sound + 0, numsamples, 1);
|
||||||
if (avierr == AVIERR_NONE)
|
if (avierr == AVIERR_NONE)
|
||||||
avierr = avi_append_sound_samples(m_avifile, 1, sound + 1, numsamples, 1);
|
avierr = avi_append_sound_samples(m_avi_file, 1, sound + 1, numsamples, 1);
|
||||||
if (avierr != AVIERR_NONE)
|
if (avierr != AVIERR_NONE)
|
||||||
end_recording();
|
end_recording(MF_AVI);
|
||||||
|
|
||||||
g_profiler.stop();
|
g_profiler.stop();
|
||||||
}
|
}
|
||||||
@ -505,7 +529,8 @@ void video_manager::add_sound_to_recording(const INT16 *sound, int numsamples)
|
|||||||
void video_manager::exit()
|
void video_manager::exit()
|
||||||
{
|
{
|
||||||
// stop recording any movie
|
// stop recording any movie
|
||||||
end_recording();
|
end_recording(MF_AVI);
|
||||||
|
end_recording(MF_MNG);
|
||||||
|
|
||||||
// free the snapshot target
|
// free the snapshot target
|
||||||
machine().render().target_free(m_snap_target);
|
machine().render().target_free(m_snap_target);
|
||||||
@ -541,7 +566,8 @@ void video_manager::screenless_update_callback(void *ptr, int param)
|
|||||||
|
|
||||||
void video_manager::postload()
|
void video_manager::postload()
|
||||||
{
|
{
|
||||||
m_movie_next_frame_time = machine().time();
|
m_avi_next_frame_time = machine().time();
|
||||||
|
m_mng_next_frame_time = machine().time();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1189,7 +1215,7 @@ file_error video_manager::open_next(emu_file &file, const char *extension)
|
|||||||
void video_manager::record_frame()
|
void video_manager::record_frame()
|
||||||
{
|
{
|
||||||
// ignore if nothing to do
|
// ignore if nothing to do
|
||||||
if (m_mngfile == NULL && m_avifile == NULL)
|
if (m_mng_file == NULL && m_avi_file == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// start the profiler and get the current time
|
// start the profiler and get the current time
|
||||||
@ -1199,27 +1225,36 @@ void video_manager::record_frame()
|
|||||||
// create the bitmap
|
// create the bitmap
|
||||||
create_snapshot_bitmap(NULL);
|
create_snapshot_bitmap(NULL);
|
||||||
|
|
||||||
// loop until we hit the right time
|
// handle an AVI recording
|
||||||
while (m_movie_next_frame_time <= curtime)
|
if (m_avi_file != NULL)
|
||||||
{
|
{
|
||||||
// handle an AVI recording
|
// loop until we hit the right time
|
||||||
if (m_avifile != NULL)
|
while (m_avi_next_frame_time <= curtime)
|
||||||
{
|
{
|
||||||
// write the next frame
|
// write the next frame
|
||||||
avi_error avierr = avi_append_video_frame(m_avifile, m_snap_bitmap);
|
avi_error avierr = avi_append_video_frame(m_avi_file, m_snap_bitmap);
|
||||||
if (avierr != AVIERR_NONE)
|
if (avierr != AVIERR_NONE)
|
||||||
{
|
{
|
||||||
g_profiler.stop();
|
g_profiler.stop();
|
||||||
return end_recording();
|
end_recording(MF_AVI);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// advance time
|
||||||
|
m_avi_next_frame_time += m_avi_frame_period;
|
||||||
|
m_avi_frame++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// handle a MNG recording
|
|
||||||
if (m_mngfile != NULL)
|
// handle a MNG recording
|
||||||
|
if (m_mng_file != NULL)
|
||||||
|
{
|
||||||
|
// loop until we hit the right time
|
||||||
|
while (m_mng_next_frame_time <= curtime)
|
||||||
{
|
{
|
||||||
// set up the text fields in the movie info
|
// set up the text fields in the movie info
|
||||||
png_info pnginfo = { 0 };
|
png_info pnginfo = { 0 };
|
||||||
if (m_movie_frame == 0)
|
if (m_mng_frame == 0)
|
||||||
{
|
{
|
||||||
astring text1(emulator_info::get_appname(), " ", build_version);
|
astring text1(emulator_info::get_appname(), " ", build_version);
|
||||||
astring text2(machine().system().manufacturer, " ", machine().system().description);
|
astring text2(machine().system().manufacturer, " ", machine().system().description);
|
||||||
@ -1230,19 +1265,21 @@ void video_manager::record_frame()
|
|||||||
// write the next frame
|
// write the next frame
|
||||||
const rgb_t *palette = (machine().first_screen() !=NULL && machine().first_screen()->palette() != NULL) ? machine().first_screen()->palette()->palette()->entry_list_adjusted() : NULL;
|
const rgb_t *palette = (machine().first_screen() !=NULL && machine().first_screen()->palette() != NULL) ? machine().first_screen()->palette()->palette()->entry_list_adjusted() : NULL;
|
||||||
int entries = (machine().first_screen() !=NULL && machine().first_screen()->palette() != NULL) ? machine().first_screen()->palette()->entries() : 0;
|
int entries = (machine().first_screen() !=NULL && machine().first_screen()->palette() != NULL) ? machine().first_screen()->palette()->entries() : 0;
|
||||||
png_error error = mng_capture_frame(*m_mngfile, &pnginfo, m_snap_bitmap, entries, palette);
|
png_error error = mng_capture_frame(*m_mng_file, &pnginfo, m_snap_bitmap, entries, palette);
|
||||||
png_free(&pnginfo);
|
png_free(&pnginfo);
|
||||||
if (error != PNGERR_NONE)
|
if (error != PNGERR_NONE)
|
||||||
{
|
{
|
||||||
g_profiler.stop();
|
g_profiler.stop();
|
||||||
return end_recording();
|
end_recording(MF_MNG);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// advance time
|
||||||
|
m_mng_next_frame_time += m_mng_frame_period;
|
||||||
|
m_mng_frame++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// advance time
|
|
||||||
m_movie_next_frame_time += m_movie_frame_period;
|
|
||||||
m_movie_frame++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_profiler.stop();
|
g_profiler.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1264,12 +1301,12 @@ void video_manager::toggle_record_movie()
|
|||||||
{
|
{
|
||||||
if (!is_recording())
|
if (!is_recording())
|
||||||
{
|
{
|
||||||
begin_recording(NULL, video_manager::MF_MNG);
|
begin_recording(NULL, MF_MNG);
|
||||||
popmessage("REC START");
|
popmessage("REC START");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
end_recording();
|
end_recording(MF_MNG);
|
||||||
popmessage("REC STOP");
|
popmessage("REC STOP");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ public:
|
|||||||
bool throttled() const { return m_throttled; }
|
bool throttled() const { return m_throttled; }
|
||||||
float throttle_rate() const { return m_throttle_rate; }
|
float throttle_rate() const { return m_throttle_rate; }
|
||||||
bool fastforward() const { return m_fastforward; }
|
bool fastforward() const { return m_fastforward; }
|
||||||
bool is_recording() const { return (m_mngfile != NULL || m_avifile != NULL); }
|
bool is_recording() const { return (m_mng_file != NULL || m_avi_file != NULL); }
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
void set_frameskip(int frameskip);
|
void set_frameskip(int frameskip);
|
||||||
@ -89,8 +89,8 @@ public:
|
|||||||
void save_active_screen_snapshots();
|
void save_active_screen_snapshots();
|
||||||
|
|
||||||
// movies
|
// movies
|
||||||
void begin_recording(const char *name, movie_format format = MF_AVI);
|
void begin_recording(const char *name, movie_format format);
|
||||||
void end_recording();
|
void end_recording(movie_format format);
|
||||||
void add_sound_to_recording(const INT16 *sound, int numsamples);
|
void add_sound_to_recording(const INT16 *sound, int numsamples);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -165,12 +165,17 @@ private:
|
|||||||
INT32 m_snap_width; // width of snapshots (0 == auto)
|
INT32 m_snap_width; // width of snapshots (0 == auto)
|
||||||
INT32 m_snap_height; // height of snapshots (0 == auto)
|
INT32 m_snap_height; // height of snapshots (0 == auto)
|
||||||
|
|
||||||
// movie recording
|
// movie recording - MNG
|
||||||
auto_pointer<emu_file> m_mngfile; // handle to the open movie file
|
auto_pointer<emu_file> m_mng_file; // handle to the open movie file
|
||||||
avi_file * m_avifile; // handle to the open movie file
|
attotime m_mng_frame_period; // period of a single movie frame
|
||||||
attotime m_movie_frame_period; // period of a single movie frame
|
attotime m_mng_next_frame_time; // time of next frame
|
||||||
attotime m_movie_next_frame_time; // time of next frame
|
UINT32 m_mng_frame; // current movie frame number
|
||||||
UINT32 m_movie_frame; // current movie frame number
|
|
||||||
|
// movie recording - AVI
|
||||||
|
avi_file * 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
|
||||||
|
|
||||||
static const UINT8 s_skiptable[FRAMESKIP_LEVELS][FRAMESKIP_LEVELS];
|
static const UINT8 s_skiptable[FRAMESKIP_LEVELS][FRAMESKIP_LEVELS];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user