mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Added support for dumping avi files (thanks baby.lueshi). Use Microsoft Video 1 codec for starters. Make sure to check the dump rendered frames box in the video plugin settings, or it won't work.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2781 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -90,7 +90,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib glew32s.lib libjpeg.lib glu32.lib rpcrt4.lib"
|
||||
AdditionalDependencies="comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib glew32s.lib libjpeg.lib glu32.lib rpcrt4.lib vfw32.lib"
|
||||
OutputFile="..\..\..\Binary\Win32\Plugins\Plugin_VideoOGL.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
@ -199,7 +199,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib libjpeg64.lib glu32.lib rpcrt4.lib glew64s.lib"
|
||||
AdditionalDependencies="comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib libjpeg64.lib glu32.lib rpcrt4.lib glew64s.lib vfw32.lib"
|
||||
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_VideoOGL.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
@ -298,7 +298,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib glew32s.lib libjpeg.lib glu32.lib rpcrt4.lib"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib glew32s.lib libjpeg.lib glu32.lib rpcrt4.lib vfw32.lib"
|
||||
OutputFile="..\..\..\Binary\Win32/Plugins\Plugin_VideoOGLD.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
@ -396,7 +396,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib libjpeg64.lib glu32.lib glew64s.lib rpcrt4.lib"
|
||||
AdditionalDependencies="comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib libjpeg64.lib glu32.lib glew64s.lib rpcrt4.lib vfw32.lib"
|
||||
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_VideoOGLD.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
@ -504,7 +504,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib glew32s.lib libjpeg.lib glu32.lib rpcrt4.lib"
|
||||
AdditionalDependencies="comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib glew32s.lib libjpeg.lib glu32.lib rpcrt4.lib vfw32.lib"
|
||||
OutputFile="..\..\..\Binary\Win32\Plugins\Plugin_VideoOGLDF.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
@ -614,7 +614,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib libjpeg64.lib glu32.lib glew64s.lib rpcrt4.lib"
|
||||
AdditionalDependencies="comctl32.lib winmm.lib cg.lib cgGL.lib opengl32.lib libjpeg64.lib glu32.lib glew64s.lib rpcrt4.lib vfw32.lib"
|
||||
OutputFile="..\..\..\Binary\x64\Plugins\Plugin_VideoOGLDF.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
|
@ -61,6 +61,7 @@ void Config::Load()
|
||||
iniFile.Get("Settings", "DLOptimize", &iCompileDLsLevel, 0);
|
||||
iniFile.Get("Settings", "DumpTextures", &bDumpTextures, 0);
|
||||
iniFile.Get("Settings", "DumpEFBTarget", &bDumpEFBTarget, 0);
|
||||
iniFile.Get("Settings", "DumpFrames", &bDumpFrames, 0);
|
||||
iniFile.Get("Settings", "ShowShaderErrors", &bShowShaderErrors, 0);
|
||||
iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0);
|
||||
iniFile.Get("Settings", "DstAlphaPass", &bDstAlphaPass, false);
|
||||
@ -143,6 +144,7 @@ void Config::Save()
|
||||
iniFile.Set("Settings", "Show", iCompileDLsLevel);
|
||||
iniFile.Set("Settings", "DumpTextures", bDumpTextures);
|
||||
iniFile.Set("Settings", "DumpEFBTarget", bDumpEFBTarget);
|
||||
iniFile.Set("Settings", "DumpFrames", bDumpFrames);
|
||||
iniFile.Set("Settings", "ShowEFBCopyRegions", bShowEFBCopyRegions);
|
||||
iniFile.Set("Settings", "ShowShaderErrors", bShowShaderErrors);
|
||||
iniFile.Set("Settings", "MSAA", iMultisampleMode);
|
||||
|
@ -84,6 +84,7 @@ struct Config
|
||||
// Utility
|
||||
bool bDumpTextures;
|
||||
bool bDumpEFBTarget;
|
||||
bool bDumpFrames;
|
||||
|
||||
// Hacks
|
||||
bool bEFBCopyDisable;
|
||||
|
@ -54,6 +54,7 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
|
||||
EVT_CHECKBOX(ID_TEXFMTCENTER, ConfigDialog::AdvancedSettingsChanged)
|
||||
EVT_CHECKBOX(ID_DUMPTEXTURES, ConfigDialog::AdvancedSettingsChanged)
|
||||
EVT_CHECKBOX(ID_DUMPEFBTARGET, ConfigDialog::AdvancedSettingsChanged)
|
||||
EVT_CHECKBOX(ID_DUMPFRAMES, ConfigDialog::AdvancedSettingsChanged)
|
||||
EVT_CHECKBOX(ID_DISABLELIGHTING, ConfigDialog::AdvancedSettingsChanged)
|
||||
EVT_CHECKBOX(ID_DISABLETEXTURING, ConfigDialog::AdvancedSettingsChanged)
|
||||
EVT_CHECKBOX(ID_EFBCOPYDISABLEHOTKEY, ConfigDialog::AdvancedSettingsChanged)
|
||||
@ -334,6 +335,18 @@ void ConfigDialog::CreateGUIControls()
|
||||
m_DumpTextures->SetValue(g_Config.bDumpTextures);
|
||||
m_DumpEFBTarget = new wxCheckBox(m_PageAdvanced, ID_DUMPEFBTARGET, wxT("Dump EFB Target"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
m_DumpEFBTarget->SetValue(g_Config.bDumpEFBTarget);
|
||||
m_DumpFrames = new wxCheckBox(m_PageAdvanced, ID_DUMPFRAMES, wxT("Dump Rendered Frames"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
#ifdef _WIN32
|
||||
m_DumpFrames->SetToolTip(wxT(
|
||||
"When dumping begins, you will be prompted to choose a video codec to"
|
||||
" encode the video in."));
|
||||
#else
|
||||
m_DumpFrames->SetToolTip(wxT(
|
||||
"!!WARNING!! This option dumps raw bitmaps of each frame, and will fill up"
|
||||
" your hard drive very quickly. Only turn this on if you have a named pipe"
|
||||
" set up for the dump or several gigabytes of space available."));
|
||||
#endif
|
||||
m_DumpFrames->SetValue(g_Config.bDumpFrames);
|
||||
|
||||
// Hacks controls
|
||||
m_SafeTextureCache = new wxCheckBox(m_PageAdvanced, ID_SAFETEXTURECACHE, wxT("Use Safe texture cache"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
|
||||
@ -394,6 +407,7 @@ void ConfigDialog::CreateGUIControls()
|
||||
sUtilities = new wxBoxSizer(wxHORIZONTAL);
|
||||
sUtilities->Add(m_DumpTextures, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
sUtilities->Add(m_DumpEFBTarget, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
sUtilities->Add(m_DumpFrames, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
sbUtilities->Add(sUtilities, 1, wxEXPAND);
|
||||
|
||||
// Sizers
|
||||
@ -525,6 +539,9 @@ void ConfigDialog::AdvancedSettingsChanged(wxCommandEvent& event)
|
||||
case ID_DUMPEFBTARGET:
|
||||
g_Config.bDumpEFBTarget = m_DumpEFBTarget->IsChecked();
|
||||
break;
|
||||
case ID_DUMPFRAMES:
|
||||
g_Config.bDumpFrames = m_DumpFrames->IsChecked();
|
||||
break;
|
||||
case ID_TEXTUREPATH:
|
||||
break;
|
||||
case ID_CHECKBOX_DISABLECOPYEFB:
|
||||
|
@ -106,6 +106,7 @@ class ConfigDialog : public wxDialog
|
||||
wxCheckBox *m_DstAlphaPass;
|
||||
wxCheckBox *m_DumpTextures;
|
||||
wxCheckBox *m_DumpEFBTarget;
|
||||
wxCheckBox *m_DumpFrames;
|
||||
wxStaticBox * m_StaticBox_EFB;
|
||||
wxCheckBox *m_CheckBox_DisableCopyEFB;
|
||||
wxRadioButton *m_Radio_CopyEFBToRAM, *m_Radio_CopyEFBToGL;
|
||||
@ -161,6 +162,7 @@ class ConfigDialog : public wxDialog
|
||||
|
||||
ID_DUMPTEXTURES,
|
||||
ID_DUMPEFBTARGET,
|
||||
ID_DUMPFRAMES,
|
||||
ID_TEXTUREPATH,
|
||||
|
||||
ID_CHECKBOX_DISABLECOPYEFB,
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
#include "GLUtil.h"
|
||||
|
||||
@ -29,6 +30,7 @@
|
||||
#include <mmsystem.h>
|
||||
#endif
|
||||
|
||||
#include "CommonPaths.h"
|
||||
#include "Config.h"
|
||||
#include "Profiler.h"
|
||||
#include "Statistics.h"
|
||||
@ -52,6 +54,7 @@
|
||||
#include "main.h" // Local
|
||||
#ifdef _WIN32
|
||||
#include "OS/Win32.h"
|
||||
#include "AVIDump.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
@ -71,6 +74,13 @@ RasterFont* s_pfont = NULL;
|
||||
|
||||
static bool s_bFullscreen = false;
|
||||
|
||||
static bool s_bLastFrameDumped = false;
|
||||
#ifdef _WIN32
|
||||
static bool s_bAVIDumping = false;
|
||||
#else
|
||||
static FILE* f_pFrameDump;
|
||||
#endif
|
||||
|
||||
static int nZBufferRender = 0; // if > 0, then use zbuffer render, and count down.
|
||||
|
||||
// 1 for no MSAA. Use s_MSAASamples > 1 to check for MSAA.
|
||||
@ -484,6 +494,15 @@ void Renderer::Shutdown(void)
|
||||
glDeleteFramebuffersEXT(1, &s_uFramebuffer);
|
||||
s_uFramebuffer = 0;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if(s_bAVIDumping) {
|
||||
AVIDump::Stop();
|
||||
}
|
||||
#else
|
||||
if(f_pFrameDump != NULL) {
|
||||
fclose(f_pFrameDump);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Renderer::InitializeGL()
|
||||
@ -1092,6 +1111,81 @@ void Renderer::Swap(const TRectangle& rc)
|
||||
s_criticalScreenshot.Leave();
|
||||
}
|
||||
|
||||
// Frame dumps are handled a little differently in Windows
|
||||
#ifdef _WIN32
|
||||
if (g_Config.bDumpFrames) {
|
||||
s_criticalScreenshot.Enter();
|
||||
int w = OpenGL_GetBackbufferWidth();
|
||||
int h = OpenGL_GetBackbufferHeight();
|
||||
u8 *data = (u8 *) malloc(3 * w * h);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(0, 0, w, h, GL_BGR, GL_UNSIGNED_BYTE, data);
|
||||
if (glGetError() == GL_NO_ERROR) {
|
||||
if (!s_bLastFrameDumped) {
|
||||
s_bAVIDumping = AVIDump::Start(EmuWindow::GetChildParentWnd(), w, h);
|
||||
if (!s_bAVIDumping) {
|
||||
PanicAlert("Error dumping frames to AVI.");
|
||||
} else {
|
||||
char msg [255];
|
||||
sprintf(msg, "Dumping Frames to \"%s/framedump0.avi\" (%dx%d RGB24)", FULL_FRAMES_DIR, w, h);
|
||||
OSD::AddMessage(msg, 2000);
|
||||
}
|
||||
}
|
||||
if (s_bAVIDumping) {
|
||||
AVIDump::AddFrame((char *) data);
|
||||
}
|
||||
s_bLastFrameDumped = true;
|
||||
}
|
||||
free(data);
|
||||
s_criticalScreenshot.Leave();
|
||||
} else {
|
||||
if(s_bLastFrameDumped && s_bAVIDumping) {
|
||||
AVIDump::Stop();
|
||||
s_bAVIDumping = false;
|
||||
}
|
||||
|
||||
s_bLastFrameDumped = false;
|
||||
}
|
||||
#else
|
||||
if (g_Config.bDumpFrames) {
|
||||
s_criticalScreenshot.Enter();
|
||||
char movie_file_name[255];
|
||||
int w = OpenGL_GetBackbufferWidth();
|
||||
int h = OpenGL_GetBackbufferHeight();
|
||||
u8 *data = (u8 *) malloc(3 * w * h);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
if (glGetError() == GL_NO_ERROR) {
|
||||
if (!s_bLastFrameDumped) {
|
||||
sprintf(movie_file_name, "%s/framedump.raw", FULL_FRAMES_DIR);
|
||||
f_pFrameDump = fopen(movie_file_name, "wb");
|
||||
if (f_pFrameDump == NULL) {
|
||||
PanicAlert("Error opening framedump.raw for writing.");
|
||||
} else {
|
||||
char msg [255];
|
||||
sprintf(msg, "Dumping Frames to \"%s\" (%dx%d RGB24)", movie_file_name, w, h);
|
||||
OSD::AddMessage(msg, 2000);
|
||||
}
|
||||
}
|
||||
if (f_pFrameDump != NULL) {
|
||||
FlipImageData(data, w, h);
|
||||
fwrite(data, w * 3, h, f_pFrameDump);
|
||||
fflush(f_pFrameDump);
|
||||
}
|
||||
s_bLastFrameDumped = true;
|
||||
}
|
||||
free(data);
|
||||
s_criticalScreenshot.Leave();
|
||||
} else {
|
||||
if(s_bLastFrameDumped && f_pFrameDump != NULL) {
|
||||
fclose(f_pFrameDump);
|
||||
f_pFrameDump = NULL;
|
||||
}
|
||||
|
||||
s_bLastFrameDumped = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Place messages on the picture, then copy it to the screen
|
||||
SwapBuffers();
|
||||
s_bNativeResolution = g_Config.bNativeResolution;
|
||||
@ -1336,6 +1430,20 @@ bool Renderer::SaveRenderTarget(const char *filename, int w, int h)
|
||||
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
return false;
|
||||
FlipImageData(data, w, h);
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
wxImage a(w, h, data);
|
||||
a.SaveFile(wxString::FromAscii(filename), wxBITMAP_TYPE_BMP);
|
||||
bool result = true;
|
||||
#else
|
||||
bool result = SaveTGA(filename, w, h, data);
|
||||
free(data);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
void Renderer::FlipImageData(u8 *data, int w, int h)
|
||||
{
|
||||
// Flip image upside down. Damn OpenGL.
|
||||
for (int y = 0; y < h / 2; y++)
|
||||
{
|
||||
@ -1346,16 +1454,6 @@ bool Renderer::SaveRenderTarget(const char *filename, int w, int h)
|
||||
std::swap(data[(y * w + x) * 3 + 2], data[((h - 1 - y) * w + x) * 3 + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
wxImage a(w, h, data);
|
||||
a.SaveFile(wxString::FromAscii(filename), wxBITMAP_TYPE_BMP);
|
||||
bool result = true;
|
||||
#else
|
||||
bool result = SaveTGA(filename, w, h, data);
|
||||
free(data);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -100,6 +100,7 @@ public:
|
||||
static void RenderText(const char* pstr, int left, int top, u32 color);
|
||||
static void DrawDebugText();
|
||||
static void SetScreenshot(const char *filename);
|
||||
static void FlipImageData(u8 *data, int w, int h);
|
||||
static bool SaveRenderTarget(const char *filename, int w, int h);
|
||||
|
||||
// Finish up the current frame, print some stats
|
||||
|
Reference in New Issue
Block a user