Add Audio Dumping to File
This commit is contained in:
parent
78d1af4b50
commit
645cb4d69e
14 changed files with 240 additions and 5 deletions
|
@ -329,6 +329,7 @@ static ConfigSetting generalSettings[] = {
|
||||||
ConfigSetting("ScreenshotsAsPNG", &g_Config.bScreenshotsAsPNG, false, true, true),
|
ConfigSetting("ScreenshotsAsPNG", &g_Config.bScreenshotsAsPNG, false, true, true),
|
||||||
ConfigSetting("UseFFV1", &g_Config.bUseFFV1, false),
|
ConfigSetting("UseFFV1", &g_Config.bUseFFV1, false),
|
||||||
ConfigSetting("DumpFrames", &g_Config.bDumpFrames, false),
|
ConfigSetting("DumpFrames", &g_Config.bDumpFrames, false),
|
||||||
|
ConfigSetting("DumpAudio", &g_Config.bDumpAudio, false),
|
||||||
ConfigSetting("StateSlot", &g_Config.iCurrentStateSlot, 0, true, true),
|
ConfigSetting("StateSlot", &g_Config.iCurrentStateSlot, 0, true, true),
|
||||||
ConfigSetting("RewindFlipFrequency", &g_Config.iRewindFlipFrequency, 0, true, true),
|
ConfigSetting("RewindFlipFrequency", &g_Config.iRewindFlipFrequency, 0, true, true),
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,7 @@ public:
|
||||||
bool bScreenshotsAsPNG;
|
bool bScreenshotsAsPNG;
|
||||||
bool bUseFFV1;
|
bool bUseFFV1;
|
||||||
bool bDumpFrames;
|
bool bDumpFrames;
|
||||||
|
bool bDumpAudio;
|
||||||
bool bEnableLogging;
|
bool bEnableLogging;
|
||||||
bool bDumpDecryptedEboot;
|
bool bDumpDecryptedEboot;
|
||||||
bool bFullscreenOnDoubleclick;
|
bool bFullscreenOnDoubleclick;
|
||||||
|
|
|
@ -501,6 +501,7 @@
|
||||||
<InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AnySuitable</InlineFunctionExpansion>
|
<InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AnySuitable</InlineFunctionExpansion>
|
||||||
<InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AnySuitable</InlineFunctionExpansion>
|
<InlineFunctionExpansion Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AnySuitable</InlineFunctionExpansion>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="WaveFile.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\ext\disarm.h" />
|
<ClInclude Include="..\ext\disarm.h" />
|
||||||
|
@ -731,6 +732,7 @@
|
||||||
<ClInclude Include="Util\PPGeDraw.h" />
|
<ClInclude Include="Util\PPGeDraw.h" />
|
||||||
<ClInclude Include="Util\ppge_atlas.h" />
|
<ClInclude Include="Util\ppge_atlas.h" />
|
||||||
<ClInclude Include="..\ext\xxhash.h" />
|
<ClInclude Include="..\ext\xxhash.h" />
|
||||||
|
<ClInclude Include="WaveFile.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\android\jni\Android.mk" />
|
<None Include="..\android\jni\Android.mk" />
|
||||||
|
|
|
@ -676,6 +676,7 @@
|
||||||
<ClCompile Include="AVIDump.cpp">
|
<ClCompile Include="AVIDump.cpp">
|
||||||
<Filter>Core</Filter>
|
<Filter>Core</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="WaveFile.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="ELF\ElfReader.h">
|
<ClInclude Include="ELF\ElfReader.h">
|
||||||
|
@ -1242,6 +1243,7 @@
|
||||||
<ClInclude Include="AVIDump.h">
|
<ClInclude Include="AVIDump.h">
|
||||||
<Filter>Core</Filter>
|
<Filter>Core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="WaveFile.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="CMakeLists.txt" />
|
<None Include="CMakeLists.txt" />
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "Core/Host.h"
|
#include "Core/Host.h"
|
||||||
#include "Core/MemMapHelpers.h"
|
#include "Core/MemMapHelpers.h"
|
||||||
#include "Core/Reporting.h"
|
#include "Core/Reporting.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "Core/HLE/__sceAudio.h"
|
#include "Core/HLE/__sceAudio.h"
|
||||||
#include "Core/HLE/sceAudio.h"
|
#include "Core/HLE/sceAudio.h"
|
||||||
#include "Core/HLE/sceKernel.h"
|
#include "Core/HLE/sceKernel.h"
|
||||||
|
@ -67,6 +68,9 @@ static int audioHostIntervalCycles;
|
||||||
|
|
||||||
static s32 *mixBuffer;
|
static s32 *mixBuffer;
|
||||||
|
|
||||||
|
WaveFileWriter g_wave_writer;
|
||||||
|
bool m_logAudio;
|
||||||
|
|
||||||
// High and low watermarks, basically. For perfect emulation, the correct values are 0 and 1, respectively.
|
// High and low watermarks, basically. For perfect emulation, the correct values are 0 and 1, respectively.
|
||||||
// TODO: Tweak. Hm, there aren't actually even used currently...
|
// TODO: Tweak. Hm, there aren't actually even used currently...
|
||||||
static int chanQueueMaxSizeFactor;
|
static int chanQueueMaxSizeFactor;
|
||||||
|
@ -134,6 +138,13 @@ void __AudioInit() {
|
||||||
|
|
||||||
resampler.Clear();
|
resampler.Clear();
|
||||||
CoreTiming::RegisterMHzChangeCallback(&__AudioCPUMHzChange);
|
CoreTiming::RegisterMHzChangeCallback(&__AudioCPUMHzChange);
|
||||||
|
|
||||||
|
if (g_Config.bDumpAudio)
|
||||||
|
{
|
||||||
|
std::string audio_file_name = GetSysDirectory(DIRECTORY_VIDEO_DUMP) + "audiodump.wav";
|
||||||
|
File::CreateEmptyFile(audio_file_name);
|
||||||
|
__StartLogAudio(audio_file_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void __AudioDoState(PointerWrap &p) {
|
void __AudioDoState(PointerWrap &p) {
|
||||||
|
@ -177,6 +188,11 @@ void __AudioShutdown() {
|
||||||
mixBuffer = 0;
|
mixBuffer = 0;
|
||||||
for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)
|
for (u32 i = 0; i < PSP_AUDIO_CHANNEL_MAX + 1; i++)
|
||||||
chans[i].clear();
|
chans[i].clear();
|
||||||
|
|
||||||
|
if (g_Config.bDumpAudio)
|
||||||
|
{
|
||||||
|
__StopLogAudio();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) {
|
u32 __AudioEnqueue(AudioChannel &chan, int chanNum, bool blocking) {
|
||||||
|
@ -364,6 +380,15 @@ void __AudioUpdate() {
|
||||||
|
|
||||||
if (g_Config.bEnableSound) {
|
if (g_Config.bEnableSound) {
|
||||||
resampler.PushSamples(mixBuffer, hwBlockSize);
|
resampler.PushSamples(mixBuffer, hwBlockSize);
|
||||||
|
if (m_logAudio)
|
||||||
|
{
|
||||||
|
s16 *clamped_data = new s16[hwBlockSize * 2];
|
||||||
|
|
||||||
|
for (int i = 0; i < hwBlockSize * 2; i++) {
|
||||||
|
clamped_data[i] = clamp_s16(mixBuffer[i]);
|
||||||
|
}
|
||||||
|
g_wave_writer.AddStereoSamples(clamped_data, hwBlockSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,3 +410,32 @@ void __PushExternalAudio(const s32 *audio, int numSamples) {
|
||||||
resampler.Clear();
|
resampler.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __StartLogAudio(const std::string& filename)
|
||||||
|
{
|
||||||
|
if (!m_logAudio)
|
||||||
|
{
|
||||||
|
m_logAudio = true;
|
||||||
|
g_wave_writer.Start(filename, 44100);
|
||||||
|
g_wave_writer.SetSkipSilence(false);
|
||||||
|
NOTICE_LOG(SCEAUDIO, "Starting Audio logging");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN_LOG(SCEAUDIO, "Audio logging has already been started");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __StopLogAudio()
|
||||||
|
{
|
||||||
|
if (m_logAudio)
|
||||||
|
{
|
||||||
|
m_logAudio = false;
|
||||||
|
g_wave_writer.Stop();
|
||||||
|
NOTICE_LOG(SCEAUDIO, "Stopping Audio logging");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN_LOG(SCEAUDIO, "Audio logging has already been stopped");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "sceAudio.h"
|
#include "sceAudio.h"
|
||||||
|
#include "Core/WaveFile.h"
|
||||||
|
|
||||||
struct AudioDebugStats {
|
struct AudioDebugStats {
|
||||||
int buffered;
|
int buffered;
|
||||||
|
@ -45,3 +46,7 @@ void __AudioWakeThreads(AudioChannel &chan, int result);
|
||||||
int __AudioMix(short *outstereo, int numSamples, int sampleRate);
|
int __AudioMix(short *outstereo, int numSamples, int sampleRate);
|
||||||
const AudioDebugStats *__AudioGetDebugStats();
|
const AudioDebugStats *__AudioGetDebugStats();
|
||||||
void __PushExternalAudio(const s32 *audio, int numSamples); // Should not be used in-game, only at the menu!
|
void __PushExternalAudio(const s32 *audio, int numSamples); // Should not be used in-game, only at the menu!
|
||||||
|
|
||||||
|
// Audio Dumping stuff
|
||||||
|
void __StartLogAudio(const std::string& filename);
|
||||||
|
void __StopLogAudio();
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "Common/ChunkFile.h"
|
#include "Common/ChunkFile.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Core/WaveFile.h"
|
||||||
|
|
||||||
struct AudioDebugStats;
|
struct AudioDebugStats;
|
||||||
|
|
||||||
|
|
116
Core/WaveFile.cpp
Normal file
116
Core/WaveFile.cpp
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
// Copyright 2008 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Core/WaveFile.h"
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/MsgHandler.h"
|
||||||
|
#include "Core/Config.h"
|
||||||
|
|
||||||
|
constexpr size_t WaveFileWriter::BUFFER_SIZE;
|
||||||
|
|
||||||
|
WaveFileWriter::WaveFileWriter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WaveFileWriter::~WaveFileWriter()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRate)
|
||||||
|
{
|
||||||
|
// Check if the file is already open
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
PanicAlert("The file %s was already open, the file header will not be written.",
|
||||||
|
filename.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.Open(filename, "wb");
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
PanicAlert("The file %s could not be opened for writing. Please check if it's already opened "
|
||||||
|
"by another program.",
|
||||||
|
filename.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_size = 0;
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// Write file header
|
||||||
|
// -----------------
|
||||||
|
Write4("RIFF");
|
||||||
|
Write(100 * 1000 * 1000); // write big value in case the file gets truncated
|
||||||
|
Write4("WAVE");
|
||||||
|
Write4("fmt ");
|
||||||
|
|
||||||
|
Write(16); // size of fmt block
|
||||||
|
Write(0x00020001); // two channels, uncompressed
|
||||||
|
|
||||||
|
const u32 sample_rate = HLESampleRate;
|
||||||
|
Write(sample_rate);
|
||||||
|
Write(sample_rate * 2 * 2); // two channels, 16bit
|
||||||
|
|
||||||
|
Write(0x00100004);
|
||||||
|
Write4("data");
|
||||||
|
Write(100 * 1000 * 1000 - 32);
|
||||||
|
|
||||||
|
// We are now at offset 44
|
||||||
|
if (file.Tell() != 44)
|
||||||
|
PanicAlert("Wrong offset: %lld", (long long)file.Tell());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveFileWriter::Stop()
|
||||||
|
{
|
||||||
|
// u32 file_size = (u32)ftello(file);
|
||||||
|
file.Seek(4, SEEK_SET);
|
||||||
|
Write(audio_size + 36);
|
||||||
|
|
||||||
|
file.Seek(40, SEEK_SET);
|
||||||
|
Write(audio_size);
|
||||||
|
|
||||||
|
file.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveFileWriter::Write(u32 value)
|
||||||
|
{
|
||||||
|
file.WriteArray(&value, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveFileWriter::Write4(const char* ptr)
|
||||||
|
{
|
||||||
|
file.WriteBytes(ptr, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveFileWriter::AddStereoSamples(const short* sample_data, u32 count)
|
||||||
|
{
|
||||||
|
if (!file)
|
||||||
|
PanicAlert("WaveFileWriter - file not open.");
|
||||||
|
|
||||||
|
if (count > BUFFER_SIZE * 2)
|
||||||
|
PanicAlert("WaveFileWriter - buffer too small (count = %u).", count);
|
||||||
|
|
||||||
|
if (skip_silence)
|
||||||
|
{
|
||||||
|
bool all_zero = true;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < count * 2; i++)
|
||||||
|
{
|
||||||
|
if (sample_data[i])
|
||||||
|
all_zero = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_zero)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.WriteBytes(sample_data, count * 4);
|
||||||
|
audio_size += count * 4;
|
||||||
|
}
|
44
Core/WaveFile.h
Normal file
44
Core/WaveFile.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright 2008 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2+
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
// Class: WaveFileWriter
|
||||||
|
// Description: Simple utility class to make it easy to write long 16-bit stereo
|
||||||
|
// audio streams to disk.
|
||||||
|
// Use Start() to start recording to a file, and AddStereoSamples to add wave data.
|
||||||
|
// The float variant will convert from -1.0-1.0 range and clamp.
|
||||||
|
// Alternatively, AddSamplesBE for big endian wave data.
|
||||||
|
// If Stop is not called when it destructs, the destructor will call Stop().
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
#include "Common/CommonTypes.h"
|
||||||
|
#include "Common/FileUtil.h"
|
||||||
|
|
||||||
|
class WaveFileWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WaveFileWriter();
|
||||||
|
~WaveFileWriter();
|
||||||
|
|
||||||
|
bool Start(const std::string& filename, unsigned int HLESampleRate);
|
||||||
|
void Stop();
|
||||||
|
|
||||||
|
void SetSkipSilence(bool skip) { skip_silence = skip; }
|
||||||
|
void AddStereoSamples(const short* sample_data, u32 count);
|
||||||
|
u32 GetAudioSize() const { return audio_size; }
|
||||||
|
private:
|
||||||
|
static constexpr size_t BUFFER_SIZE = 32 * 1024;
|
||||||
|
|
||||||
|
File::IOFile file;
|
||||||
|
bool skip_silence = false;
|
||||||
|
u32 audio_size = 0;
|
||||||
|
std::array<short, BUFFER_SIZE> conv_buffer{};
|
||||||
|
void Write(u32 value);
|
||||||
|
void Write4(const char* ptr);
|
||||||
|
};
|
||||||
|
|
|
@ -678,6 +678,7 @@ void GameSettingsScreen::CreateViews() {
|
||||||
systemSettings->Add(new CheckBox(&g_Config.bScreenshotsAsPNG, sy->T("Screenshots as PNG")));
|
systemSettings->Add(new CheckBox(&g_Config.bScreenshotsAsPNG, sy->T("Screenshots as PNG")));
|
||||||
systemSettings->Add(new CheckBox(&g_Config.bDumpFrames, sy->T("Dump Frames")));
|
systemSettings->Add(new CheckBox(&g_Config.bDumpFrames, sy->T("Dump Frames")));
|
||||||
systemSettings->Add(new CheckBox(&g_Config.bUseFFV1, sy->T("Use FFV1 for Frame Dumps")));
|
systemSettings->Add(new CheckBox(&g_Config.bUseFFV1, sy->T("Use FFV1 for Frame Dumps")));
|
||||||
|
systemSettings->Add(new CheckBox(&g_Config.bDumpAudio, sy->T("Dump Audio")));
|
||||||
#endif
|
#endif
|
||||||
systemSettings->Add(new CheckBox(&g_Config.bDayLightSavings, sy->T("Day Light Saving")));
|
systemSettings->Add(new CheckBox(&g_Config.bDayLightSavings, sy->T("Day Light Saving")));
|
||||||
static const char *dateFormat[] = { "YYYYMMDD", "MMDDYYYY", "DDMMYYYY"};
|
static const char *dateFormat[] = { "YYYYMMDD", "MMDDYYYY", "DDMMYYYY"};
|
||||||
|
|
|
@ -276,6 +276,7 @@ namespace MainWindow {
|
||||||
// Movie menu
|
// Movie menu
|
||||||
TranslateMenuItem(menu, ID_MOVIE_DUMPFRAMES);
|
TranslateMenuItem(menu, ID_MOVIE_DUMPFRAMES);
|
||||||
TranslateMenuItem(menu, ID_MOVIE_USEFFV1);
|
TranslateMenuItem(menu, ID_MOVIE_USEFFV1);
|
||||||
|
TranslateMenuItem(menu, ID_MOVIE_DUMPAUDIO);
|
||||||
|
|
||||||
// Skip display multipliers x1-x10
|
// Skip display multipliers x1-x10
|
||||||
TranslateMenuItem(menu, ID_OPTIONS_FULLSCREEN, L"\tAlt+Return, F11");
|
TranslateMenuItem(menu, ID_OPTIONS_FULLSCREEN, L"\tAlt+Return, F11");
|
||||||
|
@ -942,6 +943,10 @@ namespace MainWindow {
|
||||||
g_Config.bUseFFV1 = !g_Config.bUseFFV1;
|
g_Config.bUseFFV1 = !g_Config.bUseFFV1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ID_MOVIE_DUMPAUDIO:
|
||||||
|
g_Config.bDumpAudio = !g_Config.bDumpAudio;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// Handle the dynamic shader switching here.
|
// Handle the dynamic shader switching here.
|
||||||
|
@ -982,6 +987,7 @@ namespace MainWindow {
|
||||||
CHECKITEM(ID_OPTIONS_IGNOREWINKEY, g_Config.bIgnoreWindowsKey);
|
CHECKITEM(ID_OPTIONS_IGNOREWINKEY, g_Config.bIgnoreWindowsKey);
|
||||||
CHECKITEM(ID_MOVIE_DUMPFRAMES, g_Config.bDumpFrames);
|
CHECKITEM(ID_MOVIE_DUMPFRAMES, g_Config.bDumpFrames);
|
||||||
CHECKITEM(ID_MOVIE_USEFFV1, g_Config.bUseFFV1);
|
CHECKITEM(ID_MOVIE_USEFFV1, g_Config.bUseFFV1);
|
||||||
|
CHECKITEM(ID_MOVIE_DUMPAUDIO, g_Config.bDumpAudio);
|
||||||
|
|
||||||
static const int displayrotationitems[] = {
|
static const int displayrotationitems[] = {
|
||||||
ID_EMULATION_ROTATION_H,
|
ID_EMULATION_ROTATION_H,
|
||||||
|
|
|
@ -449,6 +449,7 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
MENUITEM "Dump Frames", ID_MOVIE_DUMPFRAMES
|
MENUITEM "Dump Frames", ID_MOVIE_DUMPFRAMES
|
||||||
MENUITEM "Lossless Codec (FFV1)", ID_MOVIE_USEFFV1
|
MENUITEM "Lossless Codec (FFV1)", ID_MOVIE_USEFFV1
|
||||||
|
MENUITEM "Dump Audio", ID_MOVIE_DUMPAUDIO
|
||||||
END
|
END
|
||||||
|
|
||||||
POPUP "Options"
|
POPUP "Options"
|
||||||
|
|
|
@ -330,6 +330,7 @@
|
||||||
#define ID_GEDBG_WATCH 40164
|
#define ID_GEDBG_WATCH 40164
|
||||||
#define ID_MOVIE_DUMPFRAMES 40165
|
#define ID_MOVIE_DUMPFRAMES 40165
|
||||||
#define ID_MOVIE_USEFFV1 40166
|
#define ID_MOVIE_USEFFV1 40166
|
||||||
|
#define ID_MOVIE_DUMPAUDIO 40167
|
||||||
|
|
||||||
// Dummy option to let the buffered rendering hotkey cycle through all the options.
|
// Dummy option to let the buffered rendering hotkey cycle through all the options.
|
||||||
#define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500
|
#define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue