GS: Add video folder and support additional arguments for video dumping

This commit is contained in:
Tokman5 2023-01-12 18:30:39 +09:00 committed by refractionpcsx2
parent d9b537d334
commit d94e861a78
12 changed files with 243 additions and 64 deletions

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -966,7 +966,7 @@ void MainWindow::onToolsVideoCaptureToggled(bool checked)
Host::GetStringSettingValue("EmuCore/GS", "VideoCaptureContainer", Pcsx2Config::GSOptions::DEFAULT_VIDEO_CAPTURE_CONTAINER)));
const QString filter(tr("%1 Files (*.%2)").arg(container.toUpper()).arg(container));
QString path(QStringLiteral("%1.%2").arg(QString::fromStdString(GSGetBaseSnapshotFilename())).arg(container));
QString path(QStringLiteral("%1.%2").arg(QString::fromStdString(GSGetBaseVideoFilename())).arg(container));
path = QFileDialog::getSaveFileName(this, tr("Video Capture"), path, filter);
if (path.isEmpty())
{

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -321,13 +321,21 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
m_ui.videoCaptureContainer->addItem(name.toUpper(), name);
}
SettingWidgetBinder::BindWidgetToFolderSetting(sif, m_ui.videoDumpingDirectory, m_ui.videoDumpingDirectoryBrowse, m_ui.videoDumpingDirectoryOpen, m_ui.videoDumpingDirectoryReset,
"Folders", "Videos", Path::Combine(EmuFolders::DataRoot, "videos"));
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.videoCaptureContainer, "EmuCore/GS", "VideoCaptureContainer");
connect(m_ui.videoCaptureContainer, &QComboBox::currentIndexChanged, this, &GraphicsSettingsWidget::onVideoCaptureContainerChanged);
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_ui.videoCaptureBitrate, "EmuCore/GS", "VideoCaptureBitrate", Pcsx2Config::GSOptions::DEFAULT_VIDEO_CAPTURE_BITRATE);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.enableVideoCaptureArguments, "EmuCore/GS", "EnableVideoCaptureParameters", false);
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.videoCaptureArguments, "EmuCore/GS", "VideoCaptureParameters");
connect(m_ui.enableVideoCaptureArguments, &QCheckBox::stateChanged, this, &GraphicsSettingsWidget::onEnableVideoCaptureArgumentsChanged);
onVideoCaptureContainerChanged();
onEnableVideoCaptureArgumentsChanged();
}
// Display tab
@ -417,8 +425,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
tr("Control the number of Auto-CRC fixes and hacks applied to games."));
dialog->registerWidgetHelp(m_ui.blending, tr("Blending Accuracy"), tr("Basic (Recommended)"),
tr("Control the accuracy level of the GS blending unit emulation. "
"The higher the setting, the more blending is emulated in the shader accurately, and the higher the speed penalty will be. "
tr("Control the accuracy level of the GS blending unit emulation.<br> "
"The higher the setting, the more blending is emulated in the shader accurately, and the higher the speed penalty will be.<br> "
"Do note that Direct3D's blending is reduced in capability compared to OpenGL/Vulkan"));
dialog->registerWidgetHelp(m_ui.texturePreloading, tr("Texture Preloading"), tr("Full (Hash Cache)"),
@ -605,6 +613,16 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
tr("Checked"), tr("Displays warnings when settings are enabled which may break games."));
}
// Recording tab
{
dialog->registerWidgetHelp(m_ui.enableVideoCaptureArguments, tr("Enable Extra Arguments"), tr("Unchecked"), tr(""));
dialog->registerWidgetHelp(m_ui.videoCaptureArguments, tr("Extra Arguments"), tr("Leave It Blank"),
tr("Parameters passed to selected video codec.<br> "
"You must use '=' to separate key from value and ':' to separate two pairs from each other.<br> "
"For example: \"crf = 21 : preset = veryfast\""));
}
// Advanced tab
{
dialog->registerWidgetHelp(m_ui.overrideTextureBarriers, tr("Override Texture Barriers"), tr("Automatic (Default)"), tr(""));
@ -741,6 +759,12 @@ void GraphicsSettingsWidget::onVideoCaptureContainerChanged()
m_dialog->getSettingsInterface(), m_ui.videoCaptureCodec, "EmuCore/GS", "VideoCaptureCodec");
}
void GraphicsSettingsWidget::onEnableVideoCaptureArgumentsChanged()
{
const bool enabled = m_dialog->getEffectiveBoolValue("EmuCore/GS", "EnableVideoCaptureParameters", false);
m_ui.videoCaptureArguments->setEnabled(enabled);
}
void GraphicsSettingsWidget::onGpuPaletteConversionChanged(int state)
{
const bool enabled = state == Qt::CheckState::PartiallyChecked ? Host::GetBaseBoolSettingValue("EmuCore/GS", "paltex", false) : state;

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -44,6 +44,7 @@ private Q_SLOTS:
void onFullscreenModeChanged(int index);
void onShadeBoostChanged();
void onVideoCaptureContainerChanged();
void onEnableVideoCaptureArgumentsChanged();
private:
GSRendererType getEffectiveRenderer() const;

View File

@ -1649,6 +1649,143 @@
</item>
</layout>
</widget>
<widget class="QGroupBox" name="recordingTab">
<attribute name="title">
<string>Recording</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QGroupBox" name="videoDumpDirectory">
<property name="title">
<string>Video Dumping Directory</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLineEdit" name="videoDumpingDirectory">
</widget>
</item>
<item>
<widget class="QPushButton" name="videoDumpingDirectoryBrowse">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="videoDumpingDirectoryOpen">
<property name="text">
<string>Open...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="videoDumpingDirectoryReset">
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="videoCaptureOptions">
<property name="title">
<string>Capture Options</string>
</property>
<layout class="QFormLayout" name="videoCaptureFormLayout">
<item row="0" column="0">
<widget class="QLabel" name="videoCaptureCodecLabel">
<property name="text">
<string>Video Codec:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="videoCaptureCodec"/>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_9" stretch="0,0,0,0">
<item>
<widget class="QLabel" name="videoCaptureContainerLabel">
<property name="text">
<string>Container:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="videoCaptureContainer"/>
</item>
<item>
<widget class="QLabel" name="videoCaptureBitrateLabel">
<property name="text">
<string>Bitrate:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="videoCaptureBitrate">
<property name="suffix">
<string> kbps</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="enableVideoCaptureArguments">
<property name="text">
<string>Enable Extra Arguments</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="videoCaptureArguments"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="advancedTab">
<attribute name="title">
<string>Advanced</string>
@ -1742,46 +1879,6 @@
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_45">
<property name="text">
<string>Video Capture Codec:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5" stretch="1,0,0,0">
<item>
<widget class="QComboBox" name="videoCaptureCodec"/>
</item>
<item>
<widget class="QComboBox" name="videoCaptureContainer"/>
</item>
<item>
<widget class="QLabel" name="label_46">
<property name="text">
<string>Bitrate:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="videoCaptureBitrate">
<property name="suffix">
<string> kbps</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>100000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -679,7 +679,8 @@ struct Pcsx2Config
DumpPaletteTextures : 1,
LoadTextureReplacements : 1,
LoadTextureReplacementsAsync : 1,
PrecacheTextureReplacements : 1;
PrecacheTextureReplacements : 1,
EnableVideoCaptureParameters : 1;
};
};
@ -755,6 +756,7 @@ struct Pcsx2Config
std::string VideoCaptureContainer{DEFAULT_VIDEO_CAPTURE_CONTAINER};
std::string VideoCaptureCodec;
int VideoCaptureBitrate{DEFAULT_VIDEO_CAPTURE_BITRATE};
std::string VideoCaptureParameters;
std::string Adapter;
std::string HWDumpDirectory;
@ -1309,6 +1311,7 @@ namespace EmuFolders
extern std::string GameSettings;
extern std::string Textures;
extern std::string InputProfiles;
extern std::string Videos;
// Assumes that AppRoot and DataRoot have been initialized.
void SetDefaults(SettingsInterface& si);

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -4065,6 +4065,7 @@ void FullscreenUI::DrawFoldersSettingsPage()
DrawFolderSetting(bsi, ICON_FA_TV " Widescreen Cheats Directory", "Folders", "CheatsWS", EmuFolders::CheatsWS);
DrawFolderSetting(bsi, ICON_FA_MAGIC " No-Interlace Cheats Directory", "Folders", "CheatsNI", EmuFolders::CheatsNI);
DrawFolderSetting(bsi, ICON_FA_SLIDERS_H "Texture Replacements Directory", "Folders", "Textures", EmuFolders::Textures);
DrawFolderSetting(bsi, ICON_FA_SLIDERS_H "Video Dumping Directory", "Folders", "Videos", EmuFolders::Videos);
EndMenuButtons();
}

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -224,6 +224,7 @@ void Host::Internal::UpdateEmuFolders()
const std::string old_cheats_ni_directory(EmuFolders::CheatsNI);
const std::string old_memcards_directory(EmuFolders::MemoryCards);
const std::string old_textures_directory(EmuFolders::Textures);
const std::string old_videos_directory(EmuFolders::Videos);
EmuFolders::LoadConfig(*GetBaseSettingsLayer());
EmuFolders::EnsureFoldersExist();
@ -250,5 +251,12 @@ void Host::Internal::UpdateEmuFolders()
GSTextureReplacements::ReloadReplacementMap();
});
}
if (EmuFolders::Videos != old_videos_directory)
{
if (VMManager::HasValidVM())
GetMTGS().RunOnGSThread(&GSEndCapture);
}
}
}

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -956,7 +956,7 @@ BEGIN_HOTKEY_LIST(g_gs_hotkeys)
return;
}
std::string filename(fmt::format("{}.{}", GSGetBaseSnapshotFilename(), GSConfig.VideoCaptureContainer));
std::string filename(fmt::format("{}.{}", GSGetBaseVideoFilename(), GSConfig.VideoCaptureContainer));
g_gs_renderer->BeginCapture(std::move(filename));
});
}

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -69,6 +69,7 @@ void GSgifTransfer3(u8* mem, u32 size);
void GSvsync(u32 field, bool registers_written);
int GSfreeze(FreezeAction mode, freezeData* data);
std::string GSGetBaseSnapshotFilename();
std::string GSGetBaseVideoFilename();
void GSQueueSnapshot(const std::string& path, u32 gsdump_frames = 0);
void GSStopGSDump();
bool GSBeginCapture(std::string filename);

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2022 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -31,6 +31,7 @@ extern "C" {
#include "libavcodec/version.h"
#include "libavformat/avformat.h"
#include "libavformat/version.h"
#include "libavutil/dict.h"
#include "libavutil/version.h"
#include "libswscale/swscale.h"
#include "libswscale/version.h"
@ -76,7 +77,11 @@ extern "C" {
X(av_frame_get_buffer) \
X(av_frame_free) \
X(av_strerror) \
X(av_reduce)
X(av_reduce) \
X(av_dict_get_string) \
X(av_dict_parse_string) \
X(av_dict_set) \
X(av_dict_free)
#define VISIT_SWSCALE_IMPORTS(X) \
X(sws_getCachedContext) \
@ -104,6 +109,7 @@ static AVFrame* s_converted_frame = nullptr; // YUV
static AVPacket* s_video_packet = nullptr;
static s64 s_next_pts = 0;
static SwsContext* s_sws_context = nullptr;
static AVDictionary* s_codec_arguments = nullptr;
#define DECLARE_IMPORT(X) static decltype(X)* wrap_##X;
VISIT_AVCODEC_IMPORTS(DECLARE_IMPORT);
@ -303,10 +309,22 @@ bool GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float
}
}
s_codec_arguments = nullptr;
if (GSConfig.EnableVideoCaptureParameters)
{
res = wrap_av_dict_parse_string(&s_codec_arguments, GSConfig.VideoCaptureParameters.c_str(), "=", ":", 0);
if (res < 0)
{
LogAVError(res, "av_dict_parse_string() failed: ");
EndCapture();
return false;
}
}
if (output_format->flags & AVFMT_GLOBALHEADER)
s_codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
res = wrap_avcodec_open2(s_codec_context, codec, nullptr);
res = wrap_avcodec_open2(s_codec_context, codec, &s_codec_arguments);
if (res < 0)
{
LogAVError(res, "avcodec_open2() failed: ");
@ -406,7 +424,7 @@ bool GSCapture::DeliverFrame(const void* bits, int pitch, bool rgba)
s_converted_frame->pts = s_next_pts++;
int res = wrap_avcodec_send_frame(s_codec_context, s_converted_frame);
const int res = wrap_avcodec_send_frame(s_codec_context, s_converted_frame);
if (res < 0)
{
LogAVError(res, "avcodec_send_frame() failed: ");
@ -456,7 +474,7 @@ bool GSCapture::EndCapture()
std::lock_guard<std::recursive_mutex> lock(s_lock);
int res;
bool was_capturing = s_capturing;
const bool was_capturing = s_capturing;
if (was_capturing)
{
@ -504,6 +522,11 @@ bool GSCapture::EndCapture()
wrap_avformat_free_context(s_format_context);
s_format_context = nullptr;
}
if (s_codec_arguments)
{
wrap_av_dict_free(&s_codec_arguments);
s_codec_arguments = nullptr;
}
if (was_capturing)
UnloadFFmpeg();

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -799,7 +799,7 @@ void GSRenderer::VSync(u32 field, bool registers_written)
{
if (GSTexture* current = g_gs_device->GetCurrent())
{
GSVector2i size = GSCapture::GetSize();
const GSVector2i size = GSCapture::GetSize();
bool res;
GSTexture::GSMap m;
@ -836,7 +836,7 @@ void GSRenderer::QueueSnapshot(const std::string& path, u32 gsdump_frames)
m_dump_frames = gsdump_frames;
}
std::string GSGetBaseSnapshotFilename()
static std::string GSGetBaseFilename()
{
std::string filename;
@ -855,7 +855,7 @@ std::string GSGetBaseSnapshotFilename()
filename += serial;
}
time_t cur_time = time(nullptr);
const time_t cur_time = time(nullptr);
char local_time[16];
if (strftime(local_time, sizeof(local_time), "%Y%m%d%H%M%S", localtime(&cur_time)))
@ -879,8 +879,19 @@ std::string GSGetBaseSnapshotFilename()
prev_snap = cur_time;
}
return filename;
}
std::string GSGetBaseSnapshotFilename()
{
// prepend snapshots directory
return Path::Combine(EmuFolders::Snapshots, filename);
return Path::Combine(EmuFolders::Snapshots, GSGetBaseFilename());
}
std::string GSGetBaseVideoFilename()
{
// prepend video directory
return Path::Combine(EmuFolders::Videos, GSGetBaseFilename());
}
void GSRenderer::StopGSDump()

View File

@ -1,5 +1,5 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
* Copyright (C) 2002-2023 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
@ -103,6 +103,7 @@ namespace EmuFolders
std::string GameSettings;
std::string Textures;
std::string InputProfiles;
std::string Videos;
} // namespace EmuFolders
void TraceLogFilters::LoadSave(SettingsWrapper& wrap)
@ -438,6 +439,8 @@ Pcsx2Config::GSOptions::GSOptions()
LoadTextureReplacements = false;
LoadTextureReplacementsAsync = true;
PrecacheTextureReplacements = false;
EnableVideoCaptureParameters = false;
}
bool Pcsx2Config::GSOptions::operator==(const GSOptions& right) const
@ -524,6 +527,7 @@ bool Pcsx2Config::GSOptions::OptionsAreEqual(const GSOptions& right) const
OpEqu(VideoCaptureContainer) &&
OpEqu(VideoCaptureCodec) &&
OpEqu(VideoCaptureBitrate) &&
OpEqu(VideoCaptureParameters) &&
OpEqu(Adapter) &&
@ -645,6 +649,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
GSSettingBool(LoadTextureReplacements);
GSSettingBool(LoadTextureReplacementsAsync);
GSSettingBool(PrecacheTextureReplacements);
GSSettingBool(EnableVideoCaptureParameters);
GSSettingIntEnumEx(LinearPresent, "linear_present_mode");
GSSettingIntEnumEx(InterlaceMode, "deinterlace_mode");
@ -697,6 +702,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
GSSettingStringEx(VideoCaptureContainer, "VideoCaptureContainer");
GSSettingStringEx(VideoCaptureCodec, "VideoCaptureCodec");
GSSettingIntEx(VideoCaptureBitrate, "VideoCaptureBitrate");
GSSettingStringEx(VideoCaptureParameters, "VideoCaptureParameters");
GSSettingString(Adapter);
GSSettingString(HWDumpDirectory);
@ -1423,6 +1429,7 @@ void EmuFolders::SetDefaults(SettingsInterface& si)
si.SetStringValue("Folders", "Cache", "cache");
si.SetStringValue("Folders", "Textures", "textures");
si.SetStringValue("Folders", "InputProfiles", "inputprofiles");
si.SetStringValue("Folders", "Videos", "videos");
}
static std::string LoadPathFromSettings(SettingsInterface& si, const std::string& root, const char* name, const char* def)
@ -1448,6 +1455,7 @@ void EmuFolders::LoadConfig(SettingsInterface& si)
Cache = LoadPathFromSettings(si, DataRoot, "Cache", "cache");
Textures = LoadPathFromSettings(si, DataRoot, "Textures", "textures");
InputProfiles = LoadPathFromSettings(si, DataRoot, "InputProfiles", "inputprofiles");
Videos = LoadPathFromSettings(si, DataRoot, "Videos", "videos");
Console.WriteLn("BIOS Directory: %s", Bios.c_str());
Console.WriteLn("Snapshots Directory: %s", Snapshots.c_str());
@ -1462,6 +1470,7 @@ void EmuFolders::LoadConfig(SettingsInterface& si)
Console.WriteLn("Cache Directory: %s", Cache.c_str());
Console.WriteLn("Textures Directory: %s", Textures.c_str());
Console.WriteLn("Input Profile Directory: %s", InputProfiles.c_str());
Console.WriteLn("Video Dumping Directory: %s", Videos.c_str());
}
bool EmuFolders::EnsureFoldersExist()
@ -1480,6 +1489,7 @@ bool EmuFolders::EnsureFoldersExist()
result = FileSystem::CreateDirectoryPath(Cache.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(Textures.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(InputProfiles.c_str(), false) && result;
result = FileSystem::CreateDirectoryPath(Videos.c_str(), false) && result;
return result;
}