Пример #1
0
void video_manager::begin_recording(const char *name, movie_format format)
{
	// create a snapshot bitmap so we know what the target size is
	screen_device_iterator iterator = screen_device_iterator(machine().root_device());
	screen_device_iterator::auto_iterator iter = iterator.begin();
	const uint32_t count = (uint32_t)iterator.count();

	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++)
				{
					create_snapshot_bitmap(iter.current());
					begin_recording_avi(name, index, iter.current());
				}
			}
			else
			{
				create_snapshot_bitmap(nullptr);
				begin_recording_avi(name, 0, iter.current());
			}
			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++)
				{
					create_snapshot_bitmap(iter.current());
					begin_recording_mng(name, index, iter.current());
				}
			}
			else
			{
				create_snapshot_bitmap(nullptr);
				begin_recording_mng(name, 0, iter.current());
			}
			break;

		default:
			osd_printf_error("Unknown movie format: %d\n", format);
			break;
	}
}
Пример #2
0
void video_manager::save_snapshot(screen_device *screen, emu_file &file)
{
	// validate
	assert(!m_snap_native || screen != nullptr);

	// create the bitmap to pass in
	create_snapshot_bitmap(screen);

	// add two text entries describing the image
	std::string text1 = std::string(emulator_info::get_appname()).append(" ").append(build_version);
	std::string text2 = std::string(machine().system().manufacturer).append(" ").append(machine().system().description);
	png_info pnginfo = { nullptr };
	png_add_text(&pnginfo, "Software", text1.c_str());
	png_add_text(&pnginfo, "System", text2.c_str());

	// now do the actual work
	const rgb_t *palette = (screen != nullptr && screen->has_palette()) ? screen->palette().palette()->entry_list_adjusted() : nullptr;
	int entries = (screen != nullptr && screen->has_palette()) ? screen->palette().entries() : 0;
	png_error error = png_write_bitmap(file, &pnginfo, m_snap_bitmap, entries, palette);
	if (error != PNGERR_NONE)
		osd_printf_error("Error generating PNG for snapshot: png_error = %d\n", error);

	// free any data allocated
	png_free(&pnginfo);
}
Пример #3
0
void video_manager::record_frame()
{
	// ignore if nothing to do
	if (m_mngfile == NULL && m_avifile == NULL)
		return;

	// start the profiler and get the current time
	g_profiler.start(PROFILER_MOVIE_REC);
	attotime curtime = machine().time();

	// create the bitmap
	create_snapshot_bitmap(NULL);

	// loop until we hit the right time
	while (m_movie_next_frame_time <= curtime)
	{
		// handle an AVI recording
		if (m_avifile != NULL)
		{
			// write the next frame
			avi_error avierr = avi_append_video_frame(m_avifile, m_snap_bitmap);
			if (avierr != AVIERR_NONE)
			{
				g_profiler.stop();
				return end_recording();
			}
		}

		// handle a MNG recording
		if (m_mngfile != NULL)
		{
			// set up the text fields in the movie info
			png_info pnginfo = { 0 };
			if (m_movie_frame == 0)
			{
				astring text1(emulator_info::get_appname(), " ", build_version);
				astring text2(machine().system().manufacturer, " ", machine().system().description);
				png_add_text(&pnginfo, "Software", text1);
				png_add_text(&pnginfo, "System", text2);
			}

			// write the next frame
			const rgb_t *palette = (machine().palette != NULL) ? palette_entry_list_adjusted(machine().palette) : NULL;
			png_error error = mng_capture_frame(*m_mngfile, &pnginfo, m_snap_bitmap, machine().total_colors(), palette);
			png_free(&pnginfo);
			if (error != PNGERR_NONE)
			{
				g_profiler.stop();
				return end_recording();
			}
		}

		// advance time
		m_movie_next_frame_time += m_movie_frame_period;
		m_movie_frame++;
	}
	g_profiler.stop();
}
Пример #4
0
void video_manager::save_snapshot(screen_device *screen, emu_file &file)
{
	// validate
	assert(!m_snap_native || screen != NULL);

	// create the bitmap to pass in
	create_snapshot_bitmap(screen);

	// add two text entries describing the image
	astring text1(emulator_info::get_appname(), " ", build_version);
	astring text2(machine().system().manufacturer, " ", machine().system().description);
	png_info pnginfo = { 0 };
	png_add_text(&pnginfo, "Software", text1);
	png_add_text(&pnginfo, "System", text2);

	// now do the actual work
	const rgb_t *palette = (machine().palette != NULL) ? palette_entry_list_adjusted(machine().palette) : NULL;
	png_error error = png_write_bitmap(file, &pnginfo, m_snap_bitmap, machine().total_colors(), palette);
	if (error != PNGERR_NONE)
		mame_printf_error("Error generating PNG for snapshot: png_error = %d\n", error);

	// free any data allocated
	png_free(&pnginfo);
}
Пример #5
0
void video_manager::begin_recording(const char *name, movie_format format)
{
	// create a snapshot bitmap so we know what the target size is
	create_snapshot_bitmap(nullptr);

	// start up an AVI recording
	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
		screen_device *screen = machine().first_screen();
		avi_file::movie_info info;
		info.video_format = 0;
		info.video_timescale = 1000 * ((screen != nullptr) ? ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds()) : screen_device::DEFAULT_FRAME_RATE);
		info.video_sampletime = 1000;
		info.video_numsamples = 0;
		info.video_width = m_snap_bitmap.width();
		info.video_height = m_snap_bitmap.height();
		info.video_depth = 24;

		info.audio_format = 0;
		info.audio_timescale = machine().sample_rate();
		info.audio_sampletime = 1;
		info.audio_numsamples = 0;
		info.audio_channels = 2;
		info.audio_samplebits = 16;
		info.audio_samplerate = machine().sample_rate();

		// create a new temporary movie file
		osd_file::error filerr;
		std::string fullpath;
		{
			emu_file tempfile(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
			if (name != nullptr)
				filerr = tempfile.open(name);
			else
				filerr = open_next(tempfile, "avi");

			// if we succeeded, make a copy of the name and create the real file over top
			if (filerr == osd_file::error::NONE)
				fullpath = tempfile.fullpath();
		}

		if (filerr == osd_file::error::NONE)
		{
			// compute the frame time
			m_avi_frame_period = attotime::from_seconds(1000) / info.video_timescale;

			// create the file and free the string
			avi_file::error avierr = avi_file::create(fullpath, info, m_avi_file);
			if (avierr != avi_file::error::NONE)
			{
				osd_printf_error("Error creating AVI: %s\n", avi_file::error_string(avierr));
				return end_recording(format);
			}
		}
	}

	// start up a MNG recording
	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
		m_mng_file = std::make_unique<emu_file>(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
		osd_file::error filerr;
		if (name != nullptr)
			filerr = m_mng_file->open(name);
		else
			filerr = open_next(*m_mng_file, "mng");

		if (filerr == osd_file::error::NONE)
		{
			// start the capture
			screen_device *screen = machine().first_screen();
			int rate = (screen != nullptr) ? ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds()) : screen_device::DEFAULT_FRAME_RATE;
			png_error pngerr = mng_capture_start(*m_mng_file, m_snap_bitmap, rate);
			if (pngerr != PNGERR_NONE)
			{
				osd_printf_error("Error capturing MNG, png_error=%d\n", pngerr);
				return end_recording(format);
			}

			// compute the frame time
			m_mng_frame_period = attotime::from_hz(rate);
		}
		else
		{
			osd_printf_error("Error creating MNG, osd_file::error=%d\n", int(filerr));
			m_mng_file.reset();
		}
	}
}
Пример #6
0
void video_manager::record_frame()
{
	// ignore if nothing to do
	if (m_mng_file == nullptr && m_avi_file == nullptr && !m_dummy_recording)
		return;

	// start the profiler and get the current time
	g_profiler.start(PROFILER_MOVIE_REC);
	attotime curtime = machine().time();

	// create the bitmap
	create_snapshot_bitmap(nullptr);

	// handle an AVI recording
	if (m_avi_file != nullptr)
	{
		// loop until we hit the right time
		while (m_avi_next_frame_time <= curtime)
		{
			// write the next frame
			avi_file::error avierr = m_avi_file->append_video_frame(m_snap_bitmap);
			if (avierr != avi_file::error::NONE)
			{
				g_profiler.stop();
				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_mng_file != nullptr)
	{
		// loop until we hit the right time
		while (m_mng_next_frame_time <= curtime)
		{
			// set up the text fields in the movie info
			png_info pnginfo = { nullptr };
			if (m_mng_frame == 0)
			{
				std::string text1 = std::string(emulator_info::get_appname()).append(" ").append(build_version);
				std::string text2 = std::string(machine().system().manufacturer).append(" ").append(machine().system().description);
				png_add_text(&pnginfo, "Software", text1.c_str());
				png_add_text(&pnginfo, "System", text2.c_str());
			}

			// write the next frame
			screen_device *screen = machine().first_screen();
			const rgb_t *palette = (screen != nullptr && screen->has_palette()) ? screen->palette().palette()->entry_list_adjusted() : nullptr;
			int entries = (screen != nullptr && screen->has_palette()) ? screen->palette().entries() : 0;
			png_error error = mng_capture_frame(*m_mng_file, &pnginfo, m_snap_bitmap, entries, palette);
			png_free(&pnginfo);
			if (error != PNGERR_NONE)
			{
				g_profiler.stop();
				end_recording(MF_MNG);
				break;
			}

			// advance time
			m_mng_next_frame_time += m_mng_frame_period;
			m_mng_frame++;
		}
	}

	g_profiler.stop();
}
Пример #7
0
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_snapshot_bitmap(NULL);

	// reset the state
	m_movie_frame = 0;
	m_movie_next_frame_time = machine().time();

	// start up an AVI recording
	if (format == MF_AVI)
	{
		// build up information about this new movie
		avi_movie_info info;
		info.video_format = 0;
		info.video_timescale = 1000 * ((machine().primary_screen != NULL) ? ATTOSECONDS_TO_HZ(machine().primary_screen->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE);
		info.video_sampletime = 1000;
		info.video_numsamples = 0;
		info.video_width = m_snap_bitmap.width();
		info.video_height = m_snap_bitmap.height();
		info.video_depth = 24;

		info.audio_format = 0;
		info.audio_timescale = machine().sample_rate();
		info.audio_sampletime = 1;
		info.audio_numsamples = 0;
		info.audio_channels = 2;
		info.audio_samplebits = 16;
		info.audio_samplerate = machine().sample_rate();

		// create a new temporary movie file
		file_error filerr;
		astring fullpath;
		{
			emu_file tempfile(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
			if (name != NULL)
				filerr = tempfile.open(name);
			else
				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 (filerr == FILERR_NONE)
				fullpath = tempfile.fullpath();
		}

		if (filerr == FILERR_NONE)
		{
			// create the file and free the string
			avi_error avierr = avi_create(fullpath, &info, &m_avifile);
			if (avierr != AVIERR_NONE)
				mame_printf_error("Error creating AVI: %s\n", avi_error_string(avierr));
		}
	}

	// start up a MNG recording
	else if (format == MF_MNG)
	{
		// create a new movie file and start recording
		m_mngfile = auto_alloc(machine(), emu_file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS));
		file_error filerr;
		if (name != NULL)
			filerr = m_mngfile->open(name);
		else
			filerr = open_next(*m_mngfile, "mng");

		if (filerr == FILERR_NONE)
		{
			// start the capture
			int rate = (machine().primary_screen != NULL) ? ATTOSECONDS_TO_HZ(machine().primary_screen->frame_period().attoseconds) : screen_device::DEFAULT_FRAME_RATE;
			png_error pngerr = mng_capture_start(*m_mngfile, m_snap_bitmap, rate);
			if (pngerr != PNGERR_NONE)
				return end_recording();

			// compute the frame time
			m_movie_frame_period = attotime::from_hz(rate);
		}
		else
		{
			mame_printf_error("Error creating MNG\n");
			global_free(m_mngfile);
			m_mngfile = NULL;
		}
	}
}
Пример #8
0
void video_manager::record_frame()
{
	// ignore if nothing to do
	if (!is_recording())
		return;

	// start the profiler and get the current time
	g_profiler.start(PROFILER_MOVIE_REC);
	attotime curtime = machine().time();

	screen_device_iterator device_iterator = screen_device_iterator(machine().root_device());
	screen_device_iterator::auto_iterator iter = device_iterator.begin();

	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
		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)
			{
				// write the next 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(); // FIXME: double exit if this happens?
					end_recording_avi(index);
					break;
				}

				// advance time
				avi_info.m_avi_next_frame_time += avi_info.m_avi_frame_period;
				avi_info.m_avi_frame++;
			}
		}

		// handle a MNG recording
		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)
			{
				// set up the text fields in the movie info
				png_info pnginfo;
				if (mng_info.m_mng_frame == 0)
				{
					std::string text1 = std::string(emulator_info::get_appname()).append(" ").append(emulator_info::get_build_version());
					std::string text2 = std::string(machine().system().manufacturer).append(" ").append(machine().system().type.fullname());
					pnginfo.add_text("Software", text1.c_str());
					pnginfo.add_text("System", text2.c_str());
				}

				// write the next frame
				screen_device *screen = iter.current();
				const rgb_t *palette = (screen != nullptr && screen->has_palette()) ? screen->palette().palette()->entry_list_adjusted() : nullptr;
				int entries = (screen != nullptr && screen->has_palette()) ? screen->palette().entries() : 0;
				png_error error = mng_capture_frame(*mng_info.m_mng_file, pnginfo, m_snap_bitmap, entries, palette);
				if (error != PNGERR_NONE)
				{
					g_profiler.stop(); // FIXME: double exit if this happens?
					end_recording_mng(index);
					break;
				}

				// advance time
				mng_info.m_mng_next_frame_time += mng_info.m_mng_frame_period;
				mng_info.m_mng_frame++;
			}
		}

		if (!m_snap_native)
		{
			break;
		}
	}

	g_profiler.stop();
}