mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Add C game interface to construct and destroy global AVRecorder instance
This commit is contained in:
parent
82251f6fb6
commit
79b1a8fd63
4 changed files with 255 additions and 0 deletions
|
|
@ -32,6 +32,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
|||
m_aatree.c
|
||||
m_anigif.c
|
||||
m_argv.c
|
||||
m_avrecorder.cpp
|
||||
m_bbox.c
|
||||
m_cheat.c
|
||||
m_cond.c
|
||||
|
|
|
|||
193
src/m_avrecorder.cpp
Normal file
193
src/m_avrecorder.cpp
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
// RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by James Robert Roman
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "cxxutil.hpp"
|
||||
#include "m_avrecorder.hpp"
|
||||
#include "media/options.hpp"
|
||||
|
||||
#include "command.h"
|
||||
#include "i_sound.h"
|
||||
#include "m_avrecorder.h"
|
||||
#include "m_fixed.h"
|
||||
#include "screen.h" // vid global
|
||||
|
||||
using namespace srb2::media;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
namespace Res
|
||||
{
|
||||
|
||||
// Using an unscoped enum here so it can implicitly cast to
|
||||
// int (in CV_PossibleValue_t). Wrap this in a namespace so
|
||||
// access is still scoped. E.g. Res::kGame
|
||||
|
||||
enum : int32_t
|
||||
{
|
||||
kGame, // user chosen resolution, vid.width
|
||||
kBase, // smallest version maintaining aspect ratio, vid.width / vid.dupx
|
||||
kBase2x,
|
||||
kBase4x,
|
||||
kWindow, // window size (monitor in fullscreen), vid.realwidth
|
||||
kCustom, // movie_custom_resolution
|
||||
};
|
||||
|
||||
}; // namespace Res
|
||||
|
||||
CV_PossibleValue_t movie_resolution_cons_t[] = {
|
||||
{Res::kGame, "Native"},
|
||||
{Res::kBase, "Small"},
|
||||
{Res::kBase2x, "Medium"},
|
||||
{Res::kBase4x, "Large"},
|
||||
{Res::kWindow, "Window"},
|
||||
{Res::kCustom, "Custom"},
|
||||
{0, NULL}};
|
||||
|
||||
CV_PossibleValue_t movie_limit_cons_t[] = {{1, "MIN"}, {INT32_MAX, "MAX"}, {0, "Unlimited"}, {0, NULL}};
|
||||
|
||||
}; // namespace
|
||||
|
||||
consvar_t cv_movie_resolution = CVAR_INIT("movie_resolution", "Medium", CV_SAVE, movie_resolution_cons_t, NULL);
|
||||
consvar_t cv_movie_custom_resolution = CVAR_INIT("movie_custom_resolution", "640x400", CV_SAVE, NULL, NULL);
|
||||
|
||||
consvar_t cv_movie_fps = CVAR_INIT("movie_fps", "60", CV_SAVE, CV_Natural, NULL);
|
||||
consvar_t cv_movie_showfps = CVAR_INIT("movie_showfps", "Yes", CV_SAVE, CV_YesNo, NULL);
|
||||
|
||||
consvar_t cv_movie_sound = CVAR_INIT("movie_sound", "On", CV_SAVE, CV_OnOff, NULL);
|
||||
|
||||
consvar_t cv_movie_duration = CVAR_INIT("movie_duration", "Unlimited", CV_SAVE | CV_FLOAT, movie_limit_cons_t, NULL);
|
||||
consvar_t cv_movie_size = CVAR_INIT("movie_size", "8.0", CV_SAVE | CV_FLOAT, movie_limit_cons_t, NULL);
|
||||
|
||||
std::shared_ptr<AVRecorder> g_av_recorder;
|
||||
|
||||
void M_AVRecorder_AddCommands(void)
|
||||
{
|
||||
CV_RegisterVar(&cv_movie_custom_resolution);
|
||||
CV_RegisterVar(&cv_movie_duration);
|
||||
CV_RegisterVar(&cv_movie_fps);
|
||||
CV_RegisterVar(&cv_movie_resolution);
|
||||
CV_RegisterVar(&cv_movie_showfps);
|
||||
CV_RegisterVar(&cv_movie_size);
|
||||
CV_RegisterVar(&cv_movie_sound);
|
||||
|
||||
srb2::media::register_options();
|
||||
}
|
||||
|
||||
static AVRecorder::Config configure()
|
||||
{
|
||||
AVRecorder::Config cfg {};
|
||||
|
||||
if (cv_movie_duration.value > 0)
|
||||
{
|
||||
cfg.max_duration = std::chrono::duration<float>(FixedToFloat(cv_movie_duration.value));
|
||||
}
|
||||
|
||||
if (cv_movie_size.value > 0)
|
||||
{
|
||||
cfg.max_size = FixedToFloat(cv_movie_size.value) * 1024 * 1024;
|
||||
}
|
||||
|
||||
if (sound_started && cv_movie_sound.value)
|
||||
{
|
||||
cfg.audio = {
|
||||
.sample_rate = 44100,
|
||||
};
|
||||
}
|
||||
|
||||
cfg.video = {
|
||||
.frame_rate = cv_movie_fps.value,
|
||||
};
|
||||
|
||||
AVRecorder::Config::Video& v = *cfg.video;
|
||||
|
||||
auto basex = [&v](int scale)
|
||||
{
|
||||
v.width = vid.width / vid.dupx * scale;
|
||||
v.height = vid.height / vid.dupy * scale;
|
||||
};
|
||||
|
||||
switch (cv_movie_resolution.value)
|
||||
{
|
||||
case Res::kGame:
|
||||
v.width = vid.width;
|
||||
v.height = vid.height;
|
||||
break;
|
||||
|
||||
case Res::kBase:
|
||||
basex(1);
|
||||
break;
|
||||
|
||||
case Res::kBase2x:
|
||||
basex(2);
|
||||
break;
|
||||
|
||||
case Res::kBase4x:
|
||||
basex(4);
|
||||
break;
|
||||
|
||||
case Res::kWindow:
|
||||
v.width = vid.realwidth;
|
||||
v.height = vid.realheight;
|
||||
break;
|
||||
|
||||
case Res::kCustom:
|
||||
if (sscanf(cv_movie_custom_resolution.string, "%dx%d", &v.width, &v.height) != 2)
|
||||
{
|
||||
throw std::invalid_argument(fmt::format(
|
||||
"Bad movie_custom_resolution '{}', should be <width>x<height> (e.g. 640x400)",
|
||||
cv_movie_custom_resolution.string
|
||||
));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
SRB2_ASSERT(false);
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
boolean M_AVRecorder_Open(const char* filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
AVRecorder::Config cfg = configure();
|
||||
|
||||
cfg.file_name = filename;
|
||||
|
||||
g_av_recorder = std::make_shared<AVRecorder>(cfg);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
CONS_Alert(CONS_ERROR, "Exception starting video recorder: %s\n", ex.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void M_AVRecorder_Close(void)
|
||||
{
|
||||
g_av_recorder.reset();
|
||||
}
|
||||
|
||||
boolean M_AVRecorder_IsExpired(void)
|
||||
{
|
||||
SRB2_ASSERT(g_av_recorder != nullptr);
|
||||
|
||||
return g_av_recorder->invalid();
|
||||
}
|
||||
42
src/m_avrecorder.h
Normal file
42
src/m_avrecorder.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by James Robert Roman
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef M_AVRECORDER_H
|
||||
#define M_AVRECORDER_H
|
||||
|
||||
#include "typedef.h" // consvar_t
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void M_AVRecorder_AddCommands(void);
|
||||
|
||||
// True if successully opened.
|
||||
boolean M_AVRecorder_Open(const char *filename);
|
||||
|
||||
void M_AVRecorder_Close(void);
|
||||
|
||||
// Check whether AVRecorder is still valid. Call M_AVRecorder_Close if expired.
|
||||
boolean M_AVRecorder_IsExpired(void);
|
||||
|
||||
extern consvar_t
|
||||
cv_movie_custom_resolution,
|
||||
cv_movie_duration,
|
||||
cv_movie_fps,
|
||||
cv_movie_resolution,
|
||||
cv_movie_showfps,
|
||||
cv_movie_size,
|
||||
cv_movie_sound;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; // extern "C"
|
||||
#endif
|
||||
|
||||
#endif/*M_AVRECORDER_H*/
|
||||
19
src/m_avrecorder.hpp
Normal file
19
src/m_avrecorder.hpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2023 by James Robert Roman
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __M_AVRECORDER_HPP__
|
||||
#define __M_AVRECORDER_HPP__
|
||||
|
||||
#include <memory> // shared_ptr
|
||||
|
||||
#include "media/avrecorder.hpp"
|
||||
|
||||
extern std::shared_ptr<srb2::media::AVRecorder> g_av_recorder;
|
||||
|
||||
#endif // __M_AVRECORDER_HPP__
|
||||
Loading…
Add table
Reference in a new issue