mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-14 22:38:34 +00:00
Can start recording at will with -r/--record.
This commit is contained in:
parent
6f9796a3fb
commit
ab30663b37
@ -24,6 +24,7 @@
|
|||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "record/ffemu.h"
|
#include "record/ffemu.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX_PLAYERS 2
|
#define MAX_PLAYERS 2
|
||||||
@ -84,7 +85,11 @@ struct global
|
|||||||
char config_path[256];
|
char config_path[256];
|
||||||
char basename[256];
|
char basename[256];
|
||||||
|
|
||||||
|
#ifdef HAVE_FFMPEG
|
||||||
ffemu_t *rec;
|
ffemu_t *rec;
|
||||||
|
char record_path[256];
|
||||||
|
bool recording;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void parse_config(void);
|
void parse_config(void);
|
||||||
|
130
ssnes.c
130
ssnes.c
@ -85,15 +85,18 @@ static void video_frame(const uint16_t *data, unsigned width, unsigned height)
|
|||||||
if ( !g_extern.video_active )
|
if ( !g_extern.video_active )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/////////////
|
#ifdef HAVE_FFMPEG
|
||||||
struct ffemu_video_data ffemu_data = {
|
if (g_extern.recording)
|
||||||
.data = data,
|
{
|
||||||
.pitch = height == 448 || height == 478 ? 1024 : 2048,
|
struct ffemu_video_data ffemu_data = {
|
||||||
.width = width,
|
.data = data,
|
||||||
.height = height
|
.pitch = height == 448 || height == 478 ? 1024 : 2048,
|
||||||
};
|
.width = width,
|
||||||
ffemu_push_video(g_extern.rec, &ffemu_data);
|
.height = height
|
||||||
/////////////
|
};
|
||||||
|
ffemu_push_video(g_extern.rec, &ffemu_data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FILTER
|
#ifdef HAVE_FILTER
|
||||||
uint16_t output_filter[width * height * 4 * 4];
|
uint16_t output_filter[width * height * 4 * 4];
|
||||||
@ -142,16 +145,19 @@ static void audio_sample(uint16_t left, uint16_t right)
|
|||||||
if ( !g_extern.audio_active )
|
if ( !g_extern.audio_active )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/////////
|
#ifdef HAVE_FFMPEG
|
||||||
static int16_t static_data[2];
|
if (g_extern.recording)
|
||||||
static_data[0] = left;
|
{
|
||||||
static_data[1] = right;
|
static int16_t static_data[2];
|
||||||
struct ffemu_audio_data ffemu_data = {
|
static_data[0] = left;
|
||||||
.data = static_data,
|
static_data[1] = right;
|
||||||
.frames = 1
|
struct ffemu_audio_data ffemu_data = {
|
||||||
};
|
.data = static_data,
|
||||||
ffemu_push_audio(g_extern.rec, &ffemu_data);
|
.frames = 1
|
||||||
//////////
|
};
|
||||||
|
ffemu_push_audio(g_extern.rec, &ffemu_data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static float data[AUDIO_CHUNK_SIZE_NONBLOCKING];
|
static float data[AUDIO_CHUNK_SIZE_NONBLOCKING];
|
||||||
static int data_ptr = 0;
|
static int data_ptr = 0;
|
||||||
@ -210,15 +216,24 @@ static void fill_pathname(char *out_path, char *in_path, const char *replace)
|
|||||||
strcat(out_path, replace);
|
strcat(out_path, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_FFMPEG
|
||||||
|
#define FFMPEG_HELP_QUARK " | -r/--record "
|
||||||
|
#else
|
||||||
|
#define FFMPEG_HELP_QUARK
|
||||||
|
#endif
|
||||||
|
|
||||||
static void print_help(void)
|
static void print_help(void)
|
||||||
{
|
{
|
||||||
puts("=================================================");
|
puts("=================================================");
|
||||||
puts("ssnes: Simple Super Nintendo Emulator (libsnes)");
|
puts("ssnes: Simple Super Nintendo Emulator (libsnes)");
|
||||||
puts("=================================================");
|
puts("=================================================");
|
||||||
puts("Usage: ssnes [rom file] [-h/--help | -s/--save]");
|
puts("Usage: ssnes [rom file] [-h/--help | -s/--save" FFMPEG_HELP_QUARK "]");
|
||||||
puts("\t-h/--help: Show this help message");
|
puts("\t-h/--help: Show this help message");
|
||||||
puts("\t-s/--save: Path for save file (*.srm). Required when rom is input from stdin");
|
puts("\t-s/--save: Path for save file (*.srm). Required when rom is input from stdin");
|
||||||
puts("\t-c/--config: Path for config file. Defaults to $XDG_CONFIG_HOME/ssnes/ssnes.cfg");
|
puts("\t-c/--config: Path for config file. Defaults to $XDG_CONFIG_HOME/ssnes/ssnes.cfg");
|
||||||
|
#ifdef HAVE_FFMPEG
|
||||||
|
puts("\t-r/--record: Path to record video file. Settings for video/audio codecs are found in config file.");
|
||||||
|
#endif
|
||||||
puts("\t-v/--verbose: Verbose logging");
|
puts("\t-v/--verbose: Verbose logging");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,13 +248,23 @@ static void parse_input(int argc, char *argv[])
|
|||||||
struct option opts[] = {
|
struct option opts[] = {
|
||||||
{ "help", 0, NULL, 'h' },
|
{ "help", 0, NULL, 'h' },
|
||||||
{ "save", 1, NULL, 's' },
|
{ "save", 1, NULL, 's' },
|
||||||
|
#ifdef HAVE_FFMPEG
|
||||||
|
{ "record", 1, NULL, 'r' },
|
||||||
|
#endif
|
||||||
{ "verbose", 0, NULL, 'v' },
|
{ "verbose", 0, NULL, 'v' },
|
||||||
{ "config", 0, NULL, 'c' },
|
{ "config", 0, NULL, 'c' },
|
||||||
{ NULL, 0, NULL, 0 }
|
{ NULL, 0, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
char optstring[] = "hs:vc:";
|
|
||||||
|
#ifdef HAVE_FFMPEG
|
||||||
|
#define FFMPEG_RECORD_ARG "r:"
|
||||||
|
#else
|
||||||
|
#define FFMPEG_RECORD_ARG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char optstring[] = "hs:vc:" FFMPEG_RECORD_ARG;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
int c = getopt_long(argc, argv, optstring, opts, &option_index);
|
int c = getopt_long(argc, argv, optstring, opts, &option_index);
|
||||||
@ -266,6 +291,13 @@ static void parse_input(int argc, char *argv[])
|
|||||||
strncpy(g_extern.config_path, optarg, sizeof(g_extern.config_path) - 1);
|
strncpy(g_extern.config_path, optarg, sizeof(g_extern.config_path) - 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef HAVE_FFMPEG
|
||||||
|
case 'r':
|
||||||
|
strncpy(g_extern.record_path, optarg, sizeof(g_extern.record_path) - 1);
|
||||||
|
g_extern.recording = true;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
print_help();
|
print_help();
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -358,24 +390,33 @@ int main(int argc, char *argv[])
|
|||||||
load_save_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
|
load_save_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
|
||||||
load_save_file(savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
|
load_save_file(savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
|
||||||
|
|
||||||
struct ffemu_rational ntsc_fps = {60000, 1001};
|
#ifdef HAVE_FFMPEG
|
||||||
struct ffemu_rational pal_fps = {50000, 1001};
|
// Hardcode these options at the moment. Should be specificed in the config file later on.
|
||||||
////////
|
if (g_extern.recording)
|
||||||
struct ffemu_params params = {
|
{
|
||||||
.vcodec = FFEMU_VIDEO_H264,
|
struct ffemu_rational ntsc_fps = {60000, 1001};
|
||||||
.acodec = FFEMU_AUDIO_VORBIS,
|
struct ffemu_rational pal_fps = {50000, 1001};
|
||||||
.rescaler = FFEMU_RESCALER_POINT,
|
struct ffemu_params params = {
|
||||||
.out_width = 512,
|
.vcodec = FFEMU_VIDEO_H264,
|
||||||
.out_height = 448,
|
.acodec = FFEMU_AUDIO_VORBIS,
|
||||||
.channels = 2,
|
.rescaler = FFEMU_RESCALER_POINT,
|
||||||
.samplerate = 32040,
|
.out_width = 512,
|
||||||
.filename = "/tmp/ssnes.mkv",
|
.out_height = 448,
|
||||||
.fps = snes_get_region() == SNES_REGION_NTSC ? ntsc_fps : pal_fps,
|
.channels = 2,
|
||||||
.aspect_ratio = 4.0/3
|
.samplerate = 32040,
|
||||||
};
|
.filename = g_extern.record_path,
|
||||||
g_extern.rec = ffemu_new(¶ms);
|
.fps = snes_get_region() == SNES_REGION_NTSC ? ntsc_fps : pal_fps,
|
||||||
assert(g_extern.rec);
|
.aspect_ratio = 4.0/3
|
||||||
/////////
|
};
|
||||||
|
SSNES_LOG("Recording with FFmpeg to %s.\n", g_extern.record_path);
|
||||||
|
g_extern.rec = ffemu_new(¶ms);
|
||||||
|
if (!g_extern.rec)
|
||||||
|
{
|
||||||
|
SSNES_ERR("Failed to start FFmpeg recording.\n");
|
||||||
|
g_extern.recording = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
///// TODO: Modular friendly!!!
|
///// TODO: Modular friendly!!!
|
||||||
for(;;)
|
for(;;)
|
||||||
@ -403,10 +444,13 @@ int main(int argc, char *argv[])
|
|||||||
psnes_run();
|
psnes_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////
|
#ifdef HAVE_FFMPEG
|
||||||
ffemu_finalize(g_extern.rec);
|
if (g_extern.recording)
|
||||||
ffemu_free(g_extern.rec);
|
{
|
||||||
///////////
|
ffemu_finalize(g_extern.rec);
|
||||||
|
ffemu_free(g_extern.rec);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
save_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
|
save_file(g_extern.savefile_name_srm, SNES_MEMORY_CARTRIDGE_RAM);
|
||||||
save_file(savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
|
save_file(savefile_name_rtc, SNES_MEMORY_CARTRIDGE_RTC);
|
||||||
|
Loading…
Reference in New Issue
Block a user