forked from Mirrors/openclonk
Remove C4Video, StdVideo
Video recording and playback only worked on Windows, and recording only handled video, not game audio. As such, it was of fairly limited use, and there's lots of software available these days that handle both.shapetextures
parent
7475b89bd2
commit
d737dc1b05
|
@ -493,15 +493,11 @@ set(OC_CLONK_SOURCES
|
|||
src/platform/C4TimeMilliseconds.h
|
||||
src/platform/C4StdInProc.cpp
|
||||
src/platform/C4StdInProc.h
|
||||
src/platform/C4Video.cpp
|
||||
src/platform/C4Video.h
|
||||
src/platform/C4Window.h
|
||||
src/platform/C4windowswrapper.h
|
||||
src/platform/PlatformAbstraction.cpp
|
||||
src/platform/PlatformAbstraction.h
|
||||
src/platform/StdSync.h
|
||||
src/platform/StdVideo.cpp
|
||||
src/platform/StdVideo.h
|
||||
src/player/C4Player.cpp
|
||||
src/player/C4Player.h
|
||||
src/player/C4PlayerList.cpp
|
||||
|
@ -1333,20 +1329,6 @@ if(USE_COCOA)
|
|||
TARGET_LINK_LIBRARIES(openclonk-server "-framework Cocoa")
|
||||
endif()
|
||||
if (WIN32)
|
||||
# CMake is too incompetent to check whether these libraries can be linked to
|
||||
# So just pretend that everything is fine
|
||||
FINDLIB(VFW32_LIBRARIES vfw32)
|
||||
FINDLIB(wavifil32_LIBRARIES wavifil32)
|
||||
if (VFW32_LIBRARIES)
|
||||
target_link_libraries(openclonk vfw32)
|
||||
target_link_libraries(openclonk-server vfw32)
|
||||
set(HAVE_VFW32 TRUE)
|
||||
elseif(wavifil32_LIBRARIES)
|
||||
target_link_libraries(openclonk wavifil32 msvfw32)
|
||||
target_link_libraries(openclonk-server wavifil32 msvfw32)
|
||||
set(HAVE_VFW32 TRUE)
|
||||
endif()
|
||||
|
||||
target_link_libraries(openclonk ws2_32)
|
||||
target_link_libraries(openclonk-server ws2_32)
|
||||
target_link_libraries(c4group ws2_32)
|
||||
|
|
|
@ -91,8 +91,6 @@
|
|||
/* Define to 1 if you have the `__mingw_vasprintf' function. */
|
||||
#cmakedefine HAVE___MINGW_VASPRINTF 1
|
||||
|
||||
#cmakedefine HAVE_VFW32
|
||||
|
||||
/* Define to 1 if you have the <X11/extensions/Xrandr.h> header file. */
|
||||
#cmakedefine HAVE_X11_EXTENSIONS_XRANDR_H 1
|
||||
|
||||
|
|
|
@ -99,7 +99,6 @@ void C4ConfigGraphics::CompileFunc(StdCompiler *pComp)
|
|||
pComp->Value(mkNamingAdapt(ShowStartupMessages, "ShowStartupMessages", 1 ,false, true));
|
||||
pComp->Value(mkNamingAdapt(HighResLandscape, "HighResLandscape", 1 ,false, true));
|
||||
pComp->Value(mkNamingAdapt(VerboseObjectLoading, "VerboseObjectLoading", 0 ));
|
||||
pComp->Value(mkNamingAdapt(VideoModule, "VideoModule", 0 ,false, true));
|
||||
pComp->Value(mkNamingAdapt(MenuTransparency, "MenuTransparency", 1 ,false, true));
|
||||
pComp->Value(mkNamingAdapt(UpperBoard, "UpperBoard", 1 ,false, true));
|
||||
pComp->Value(mkNamingAdapt(ShowClock, "ShowClock", 0 ,false, true));
|
||||
|
|
|
@ -97,7 +97,6 @@ public:
|
|||
int32_t ShowStartupMessages;
|
||||
int32_t VerboseObjectLoading;
|
||||
int32_t HighResLandscape;
|
||||
int32_t VideoModule;
|
||||
int32_t MenuTransparency;
|
||||
int32_t UpperBoard;
|
||||
int32_t ShowClock;
|
||||
|
|
|
@ -2942,11 +2942,6 @@ bool C4Game::InitKeyboard()
|
|||
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_F7, KEYS_Control), "DbgShowActionToggle", KEYSCOPE_Generic, new C4KeyCB <C4GraphicsSystem>(GraphicsSystem, &C4GraphicsSystem::ToggleShowAction)));
|
||||
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_F8, KEYS_Control), "DbgShow8BitSurface", KEYSCOPE_Generic, new C4KeyCB <C4GraphicsSystem>(GraphicsSystem, &C4GraphicsSystem::ToggleShow8BitSurface)));
|
||||
|
||||
// video recording - improve...
|
||||
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_ADD, KEYS_Alt), "VideoEnlarge", KEYSCOPE_Generic, new C4KeyCB <C4Video> (GraphicsSystem.Video, &C4Video::Enlarge)));
|
||||
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_SUBTRACT, KEYS_Alt), "VideoReduce", KEYSCOPE_Generic, new C4KeyCB <C4Video> (GraphicsSystem.Video, &C4Video::Reduce)));
|
||||
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_MULTIPLY, KEYS_Alt), "VideoToggle", KEYSCOPE_Generic, new C4KeyCB <C4Video> (GraphicsSystem.Video, &C4Video::Toggle)));
|
||||
|
||||
// playback speed - improve...
|
||||
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_ADD, KEYS_Shift), "GameSpeedUp", KEYSCOPE_Generic, new C4KeyCB <C4Game> (*this, &C4Game::SpeedUp)));
|
||||
KeyboardInput.RegisterKey(new C4CustomKey(C4KeyCodeEx(K_SUBTRACT, KEYS_Shift), "GameSlowDown", KEYSCOPE_Generic, new C4KeyCB <C4Game> (*this, &C4Game::SlowDown)));
|
||||
|
|
|
@ -46,9 +46,6 @@ C4GraphicsSystem::~C4GraphicsSystem()
|
|||
|
||||
bool C4GraphicsSystem::Init()
|
||||
{
|
||||
// Init video module
|
||||
if (Config.Graphics.VideoModule)
|
||||
Video.Init(FullScreen.pSurface);
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
@ -61,8 +58,6 @@ void C4GraphicsSystem::Clear()
|
|||
if (pLoaderScreen) { delete pLoaderScreen; pLoaderScreen=NULL; }
|
||||
// Close viewports
|
||||
::Viewports.Clear();
|
||||
// Clear video system
|
||||
Video.Clear();
|
||||
// No debug stuff
|
||||
DeactivateDebugOutput();
|
||||
}
|
||||
|
@ -147,10 +142,6 @@ void C4GraphicsSystem::Execute()
|
|||
::pGUI->Render(false);
|
||||
}
|
||||
|
||||
// Video record & status (fullsrceen)
|
||||
if (!Application.isEditor)
|
||||
Video.Execute();
|
||||
|
||||
// done
|
||||
FinishDrawing();
|
||||
}
|
||||
|
@ -171,7 +162,6 @@ void C4GraphicsSystem::Default()
|
|||
ShowHelp=false;
|
||||
FlashMessageText[0]=0;
|
||||
FlashMessageTime=0; FlashMessageX=FlashMessageY=0;
|
||||
Video.Default();
|
||||
pLoaderScreen=NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include <C4MessageBoard.h>
|
||||
#include <C4UpperBoard.h>
|
||||
#include <C4Video.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -44,7 +43,6 @@ public:
|
|||
int Show8BitSurface; // 0 normal, 1 foreground mats, 2 background mats
|
||||
bool ShowLights;
|
||||
bool ShowMenuInfo;
|
||||
C4Video Video;
|
||||
C4LoaderScreen *pLoaderScreen;
|
||||
void Default();
|
||||
void Clear();
|
||||
|
|
|
@ -355,10 +355,6 @@ void C4Viewport::Execute()
|
|||
pDraw->PrepareRendering(w->pSurface);
|
||||
// Draw
|
||||
Draw(cgo, true);
|
||||
// Video record & status (developer mode, first player viewport)
|
||||
if (Application.isEditor)
|
||||
if (Player==0 && (this==::Viewports.GetViewport((int32_t) 0)))
|
||||
::GraphicsSystem.Video.Execute();
|
||||
// Blit output
|
||||
BlitOutput();
|
||||
}
|
||||
|
|
|
@ -123,7 +123,6 @@ public:
|
|||
friend class C4ViewportWindow;
|
||||
friend class C4ViewportList;
|
||||
friend class C4GraphicsSystem;
|
||||
friend class C4Video;
|
||||
};
|
||||
|
||||
class C4ViewportList {
|
||||
|
|
|
@ -147,7 +147,6 @@
|
|||
#define C4GUI_TabCaptionScrollTime 500 // 0.5 seconds
|
||||
|
||||
// Z-ordering of dialogs
|
||||
#define C4GUI_Z_VIDEO +3 // video dialog obstructing all
|
||||
#define C4GUI_Z_CHAT +2 // chat input dialog more important than other input dialogs
|
||||
#define C4GUI_Z_INPUT +1 // input dialogs on top of others
|
||||
#define C4GUI_Z_DEFAULT 0 // normal placement on top of viewports
|
||||
|
|
|
@ -1,302 +0,0 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 1998-2000, Matthes Bender
|
||||
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
|
||||
* Copyright (c) 2009-2013, The OpenClonk Team and contributors
|
||||
*
|
||||
* Distributed under the terms of the ISC license; see accompanying file
|
||||
* "COPYING" for details.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
||||
* See accompanying file "TRADEMARK" for details.
|
||||
*
|
||||
* To redistribute this file separately, substitute the full license texts
|
||||
* for the above references.
|
||||
*/
|
||||
|
||||
/* Captures uncompressed AVI from game view */
|
||||
|
||||
#include <C4Include.h>
|
||||
#include <C4Video.h>
|
||||
|
||||
#include <C4Viewport.h>
|
||||
#include <C4Config.h>
|
||||
#include <C4Application.h>
|
||||
#include <C4Game.h>
|
||||
#include <C4Player.h>
|
||||
#include <C4GraphicsResource.h>
|
||||
#include <C4GraphicsSystem.h>
|
||||
#include <C4PlayerList.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <StdVideo.h>
|
||||
#endif
|
||||
|
||||
C4Video::C4Video()
|
||||
{
|
||||
Default();
|
||||
}
|
||||
|
||||
C4Video::~C4Video()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void C4Video::Default()
|
||||
{
|
||||
Active=false;
|
||||
pAviFile=NULL;
|
||||
pAviStream=NULL;
|
||||
AviFrame=0;
|
||||
AspectRatio=1.333;
|
||||
X=0; Y=0;
|
||||
Width=768; Height=576;
|
||||
Buffer=NULL;
|
||||
BufferSize=0;
|
||||
InfoSize=0;
|
||||
Recording=false;
|
||||
Surface=NULL;
|
||||
ShowFlash=0;
|
||||
}
|
||||
|
||||
void C4Video::Clear()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
void C4Video::Init(C4Surface * sfcSource, int iWidth, int iHeight)
|
||||
{
|
||||
// Activate
|
||||
Active=true;
|
||||
// Set source surface
|
||||
Surface=sfcSource;
|
||||
// Set video size
|
||||
Width=iWidth; Height=iHeight;
|
||||
AspectRatio = (double) iWidth / (double) iHeight;
|
||||
}
|
||||
|
||||
bool C4Video::Enlarge()
|
||||
{
|
||||
if (!Config.Graphics.VideoModule) return false;
|
||||
Resize(+16);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C4Video::Reduce()
|
||||
{
|
||||
if (!Config.Graphics.VideoModule) return false;
|
||||
Resize(-16);
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4Video::Execute() // Record frame, draw status
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// Not active
|
||||
if (!Active) return;
|
||||
// Flash time
|
||||
if (ShowFlash) ShowFlash--;
|
||||
// Record
|
||||
if (Recording) RecordFrame();
|
||||
// Draw
|
||||
Draw();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool C4Video::Toggle()
|
||||
{
|
||||
if (!Config.Graphics.VideoModule) return false;
|
||||
if (!Recording) return(Start());
|
||||
return(Stop());
|
||||
}
|
||||
|
||||
bool C4Video::Stop()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// Recording: close file
|
||||
if (Recording) AVICloseOutput(&pAviFile,&pAviStream);
|
||||
// Recording flag
|
||||
Recording = false;
|
||||
// Clear buffer
|
||||
if (Buffer) delete [] Buffer; Buffer=NULL;
|
||||
#endif
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C4Video::Start()
|
||||
{
|
||||
// Determine new filename
|
||||
char szFilename[_MAX_PATH+1]; int iIndex=0;
|
||||
do { sprintf(szFilename,"Video%03d.avi",iIndex++); }
|
||||
while (ItemExists(szFilename));
|
||||
// Start recording
|
||||
return(Start(szFilename));
|
||||
}
|
||||
|
||||
bool C4Video::Start(const char *szFilename)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// Stop any recording
|
||||
Stop();
|
||||
// Open output file
|
||||
if (!AVIOpenOutput(szFilename,&pAviFile,&pAviStream,Width,Height))
|
||||
{
|
||||
Log("AVIOpenOutput failure");
|
||||
AVICloseOutput(&pAviFile,&pAviStream);
|
||||
return false;
|
||||
}
|
||||
// Create video buffer
|
||||
AviFrame=0;
|
||||
InfoSize = sizeof(BITMAPINFOHEADER);
|
||||
if (Config.Graphics.BitDepth == 8)
|
||||
InfoSize += sizeof(RGBQUAD)*256;
|
||||
BufferSize = InfoSize + DWordAligned(Width)*Height * Config.Graphics.BitDepth/8;
|
||||
Buffer = new BYTE[BufferSize];
|
||||
// Set bitmap info
|
||||
BITMAPINFO *pInfo = (BITMAPINFO*) Buffer;
|
||||
ZeroMem((BYTE*)pInfo,sizeof(BITMAPINFOHEADER));
|
||||
pInfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
|
||||
pInfo->bmiHeader.biPlanes=1;
|
||||
pInfo->bmiHeader.biWidth=Width;
|
||||
pInfo->bmiHeader.biHeight=Height;
|
||||
pInfo->bmiHeader.biBitCount=Config.Graphics.BitDepth;
|
||||
pInfo->bmiHeader.biCompression=0;
|
||||
pInfo->bmiHeader.biSizeImage = DWordAligned(Width)*Height * Config.Graphics.BitDepth/8;
|
||||
// Recording flag
|
||||
Recording=true;
|
||||
#endif //_WIN32
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4Video::Resize(int iChange)
|
||||
{
|
||||
// Not while recording
|
||||
if (Recording) return;
|
||||
// Resize
|
||||
Width = Clamp( Width+iChange, 56, 800 );
|
||||
Height = Clamp( (int) ((double)Width/AspectRatio), 40, 600 );
|
||||
// Adjust position
|
||||
AdjustPosition();
|
||||
// Show flash
|
||||
ShowFlash=50;
|
||||
}
|
||||
|
||||
void C4Video::Draw(C4TargetFacet &cgo)
|
||||
{
|
||||
// Not active
|
||||
if (!Active) return;
|
||||
// No show
|
||||
if (!ShowFlash) return;
|
||||
// Draw frame
|
||||
pDraw->DrawFrameDw(cgo.Surface, X+cgo.X,Y+cgo.Y,
|
||||
X+cgo.X+Width-1,Y+cgo.Y+Height-1,
|
||||
Recording ? C4RGB(0xca, 0, 0) : C4RGB(0xff, 0xff, 0xff));
|
||||
// Draw status
|
||||
StdStrBuf str;
|
||||
if (Recording) str.Format("%dx%d Frame %d",Width,Height,AviFrame);
|
||||
else str.Format("%dx%d",Width,Height);
|
||||
pDraw->TextOut(str.getData(), ::GraphicsResource.FontRegular, 1.0,cgo.Surface,cgo.X+X+4,cgo.Y+Y+3,Recording ? 0xfaFF0000 : 0xfaFFFFFF);
|
||||
}
|
||||
|
||||
bool C4Video::AdjustPosition()
|
||||
{
|
||||
// Get source player & viewport
|
||||
C4Viewport *pViewport = ::Viewports.GetFirstViewport();
|
||||
if (!pViewport) return false;
|
||||
C4Player *pPlr = ::Players.Get(pViewport->GetPlayer());
|
||||
if (!pPlr) return false;
|
||||
// Set camera position
|
||||
X = int32_t(fixtof(pPlr->ViewX) - pViewport->GetViewX() + pViewport->DrawX - Width/2);
|
||||
X = Clamp( X, 0, pViewport->ViewWdt - Width );
|
||||
Y = int32_t(fixtof(pPlr->ViewY) - pViewport->GetViewY() + pViewport->DrawY - Height/2);
|
||||
Y = Clamp( Y, 0, pViewport->ViewHgt - Height );
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void StdBlit(uint8_t *bypSource, int iSourcePitch, int iSrcBufHgt,
|
||||
int iSrcX, int iSrcY, int iSrcWdt, int iSrcHgt,
|
||||
uint8_t *bypTarget, int iTargetPitch, int iTrgBufHgt,
|
||||
int iTrgX, int iTrgY, int iTrgWdt, int iTrgHgt,
|
||||
int iBytesPerPixel=1, bool fFlip=false)
|
||||
{
|
||||
if (!bypSource || !bypTarget) return;
|
||||
if (!iTrgWdt || !iTrgHgt) return;
|
||||
int xcnt,ycnt,zcnt,sline,tline,fy;
|
||||
for (ycnt=0; ycnt<iTrgHgt; ycnt++)
|
||||
{
|
||||
fy = iSrcHgt * ycnt / iTrgHgt;
|
||||
if (iSrcBufHgt>0) sline = ( iSrcBufHgt - 1 - iSrcY - fy ) * iSourcePitch;
|
||||
else sline = ( iSrcY + fy ) * iSourcePitch;
|
||||
if (iTrgBufHgt>0) tline = ( iTrgBufHgt - 1 - iTrgY - ycnt ) * iTargetPitch;
|
||||
else tline = ( iTrgY + ycnt ) * iTargetPitch;
|
||||
if (!fFlip)
|
||||
{
|
||||
for (xcnt=0; xcnt<iTrgWdt; xcnt++)
|
||||
for (zcnt=0; zcnt<iBytesPerPixel; zcnt++)
|
||||
bypTarget [ tline + (iTrgX + xcnt) * iBytesPerPixel + zcnt]
|
||||
= bypSource [ sline + (iSrcX + iSrcWdt * xcnt / iTrgWdt) * iBytesPerPixel + zcnt ];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (xcnt=0; xcnt<iTrgWdt; xcnt++)
|
||||
for (zcnt=0; zcnt<iBytesPerPixel; zcnt++)
|
||||
bypTarget [ tline + (iTrgX + iTrgWdt - 1 -xcnt) * iBytesPerPixel + zcnt]
|
||||
= bypSource [ sline + (iSrcX + iSrcWdt * xcnt / iTrgWdt) * iBytesPerPixel + zcnt ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool C4Video::RecordFrame()
|
||||
{
|
||||
// No buffer
|
||||
if (!Buffer) return false;
|
||||
// Lock source
|
||||
int iPitch,iHeight;
|
||||
if (!Surface->Lock()) { Log("Video: lock surface failure"); Stop(); return false; }
|
||||
iPitch = Surface->PrimarySurfaceLockPitch;
|
||||
BYTE *bypBits = Surface->PrimarySurfaceLockBits;
|
||||
iHeight = Surface->Hgt;
|
||||
// Adjust source position
|
||||
if (!AdjustPosition()) { Log("Video: player/viewport failure"); Stop(); return false; }
|
||||
// Blit screen to buffer
|
||||
StdBlit((uint8_t*)bypBits,iPitch,-iHeight,
|
||||
X,Y,Width,Height,
|
||||
(uint8_t*)Buffer+InfoSize,
|
||||
DWordAligned(Width) * (Config.Graphics.BitDepth/8),Height,
|
||||
0,0,Width,Height,
|
||||
Config.Graphics.BitDepth/8);
|
||||
// Unlock source
|
||||
Surface->Unlock();
|
||||
// Write frame to file
|
||||
if (!AVIPutFrame(pAviStream,
|
||||
AviFrame,
|
||||
Buffer,InfoSize,
|
||||
Buffer+InfoSize,BufferSize-InfoSize))
|
||||
{ Log("AVIPutFrame failure"); Stop(); return false; }
|
||||
// Advance frame
|
||||
AviFrame++;
|
||||
// Show flash
|
||||
ShowFlash=1;
|
||||
// Success
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4Video::Draw()
|
||||
{
|
||||
// Not active
|
||||
if (!Active) return;
|
||||
// Get viewport
|
||||
C4Viewport *pViewport;
|
||||
if ( (pViewport = ::Viewports.GetFirstViewport()) )
|
||||
{
|
||||
C4TargetFacet cgo;
|
||||
cgo.Set(Surface,pViewport->DrawX,pViewport->DrawY,pViewport->ViewWdt,pViewport->ViewHgt,pViewport->GetViewX(),pViewport->GetViewY());
|
||||
Draw(cgo);
|
||||
}
|
||||
}
|
||||
#endif //_WIN32
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 1998-2000, Matthes Bender
|
||||
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
|
||||
* Copyright (c) 2013, The OpenClonk Team and contributors
|
||||
*
|
||||
* Distributed under the terms of the ISC license; see accompanying file
|
||||
* "COPYING" for details.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
||||
* See accompanying file "TRADEMARK" for details.
|
||||
*
|
||||
* To redistribute this file separately, substitute the full license texts
|
||||
* for the above references.
|
||||
*/
|
||||
|
||||
/* Captures uncompressed AVI from game view */
|
||||
|
||||
#ifndef INC_C4Video
|
||||
#define INC_C4Video
|
||||
|
||||
#include <C4Surface.h>
|
||||
|
||||
// avoid pulling in vfw.h in every file
|
||||
struct IAVIFile;
|
||||
struct IAVIStream;
|
||||
|
||||
class C4TargetFacet;
|
||||
|
||||
class C4Video
|
||||
{
|
||||
public:
|
||||
C4Video();
|
||||
~C4Video();
|
||||
protected:
|
||||
bool Active;
|
||||
IAVIFile * pAviFile;
|
||||
IAVIStream * pAviStream;
|
||||
int AviFrame;
|
||||
double AspectRatio;
|
||||
int X,Y,Width,Height;
|
||||
BYTE *Buffer;
|
||||
int BufferSize;
|
||||
int InfoSize;
|
||||
bool Recording;
|
||||
C4Surface * Surface;
|
||||
int ShowFlash;
|
||||
public:
|
||||
void Draw();
|
||||
void Draw(C4TargetFacet &cgo);
|
||||
void Resize(int iChange);
|
||||
bool Start(const char *szFilename);
|
||||
void Default();
|
||||
void Init(C4Surface * sfcSource, int iWidth=768, int iHeight=576);
|
||||
void Clear();
|
||||
bool Start();
|
||||
bool Stop();
|
||||
bool Toggle();
|
||||
void Execute();
|
||||
bool Reduce();
|
||||
bool Enlarge();
|
||||
protected:
|
||||
bool RecordFrame();
|
||||
bool AdjustPosition();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,351 +0,0 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 1998-2000, Matthes Bender
|
||||
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
|
||||
* Copyright (c) 2009-2013, The OpenClonk Team and contributors
|
||||
*
|
||||
* Distributed under the terms of the ISC license; see accompanying file
|
||||
* "COPYING" for details.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
||||
* See accompanying file "TRADEMARK" for details.
|
||||
*
|
||||
* To redistribute this file separately, substitute the full license texts
|
||||
* for the above references.
|
||||
*/
|
||||
|
||||
/* Some functions to help with saving AVI files using Video for Windows */
|
||||
|
||||
#include "C4Include.h"
|
||||
#ifdef _WIN32
|
||||
#ifdef HAVE_VFW32
|
||||
|
||||
#include <StdVideo.h>
|
||||
#include <C4Surface.h>
|
||||
|
||||
bool AVIOpenOutput(const char *szFilename,
|
||||
PAVIFILE *ppAviFile,
|
||||
PAVISTREAM *ppAviStream,
|
||||
int iWidth, int iHeight)
|
||||
{
|
||||
|
||||
// Init AVI system
|
||||
AVIFileInit();
|
||||
|
||||
// Create avi file
|
||||
if ( AVIFileOpenW(
|
||||
ppAviFile,
|
||||
GetWideChar(szFilename),
|
||||
OF_CREATE | OF_WRITE,
|
||||
NULL) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create stream
|
||||
AVISTREAMINFOW avi_info;
|
||||
RECT frame; frame.left=0; frame.top=0; frame.right=iWidth; frame.bottom=iHeight;
|
||||
avi_info.fccType= streamtypeVIDEO;
|
||||
avi_info.fccHandler= mmioFOURCC('M','S','V','C');
|
||||
avi_info.dwFlags= 0;
|
||||
avi_info.dwCaps= 0;
|
||||
avi_info.wPriority= 0;
|
||||
avi_info.wLanguage= 0;
|
||||
avi_info.dwScale= 1;
|
||||
avi_info.dwRate= 35;
|
||||
avi_info.dwStart= 0;
|
||||
avi_info.dwLength= 10; // ??
|
||||
avi_info.dwInitialFrames= 0;
|
||||
avi_info.dwSuggestedBufferSize= 0;
|
||||
avi_info.dwQuality= -1;
|
||||
avi_info.dwSampleSize= 0;
|
||||
avi_info.rcFrame= frame;
|
||||
avi_info.dwEditCount= 0;
|
||||
avi_info.dwFormatChangeCount= 0;
|
||||
wcscpy(avi_info.szName, L"MyRecording");
|
||||
|
||||
if ( AVIFileCreateStreamW(
|
||||
*ppAviFile,
|
||||
ppAviStream,
|
||||
&avi_info) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AVICloseOutput(PAVIFILE *ppAviFile,
|
||||
PAVISTREAM *ppAviStream)
|
||||
{
|
||||
if (ppAviStream && *ppAviStream)
|
||||
{ AVIStreamRelease(*ppAviStream); *ppAviStream=NULL; }
|
||||
if (ppAviFile && *ppAviFile)
|
||||
{ AVIFileRelease(*ppAviFile); *ppAviFile=NULL; }
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AVIPutFrame(PAVISTREAM pAviStream,
|
||||
long lFrame,
|
||||
void *lpInfo, long lInfoSize,
|
||||
void *lpData, long lDataSize)
|
||||
{
|
||||
long lBytesWritten=0,lSamplesWritten=0;
|
||||
|
||||
AVIStreamSetFormat(
|
||||
pAviStream,
|
||||
lFrame,
|
||||
lpInfo,
|
||||
lInfoSize
|
||||
);
|
||||
|
||||
if (AVIStreamWrite(
|
||||
pAviStream,
|
||||
lFrame,
|
||||
1,
|
||||
lpData,
|
||||
lDataSize,
|
||||
AVIIF_KEYFRAME,
|
||||
&lSamplesWritten,
|
||||
&lBytesWritten) != 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AVIOpenGrab(const char *szFilename,
|
||||
PAVISTREAM *ppAviStream,
|
||||
PGETFRAME *ppGetFrame,
|
||||
int &rAviLength, int &rFrameWdt, int &rFrameHgt,
|
||||
int &rFrameBitsPerPixel, int &rFramePitch)
|
||||
{
|
||||
|
||||
// Open avi stream
|
||||
if ( AVIStreamOpenFromFileW(
|
||||
ppAviStream,
|
||||
GetWideChar(szFilename),
|
||||
streamtypeVIDEO,
|
||||
0,
|
||||
OF_READ,
|
||||
NULL) != 0) return false;
|
||||
|
||||
// Get stream info
|
||||
AVISTREAMINFO avi_info;
|
||||
AVIStreamInfo(*ppAviStream,&avi_info,sizeof(avi_info));
|
||||
rAviLength=avi_info.dwLength;
|
||||
|
||||
// Open get frame
|
||||
if (!(*ppGetFrame = AVIStreamGetFrameOpen(*ppAviStream,NULL))) return false;
|
||||
|
||||
// Get sample frame
|
||||
void *pframe;
|
||||
if (!(pframe = AVIStreamGetFrame(*ppGetFrame,0))) return false;
|
||||
|
||||
// Assign sample bmp info
|
||||
BITMAPINFOHEADER *sample = (BITMAPINFOHEADER*) pframe;
|
||||
rFrameWdt = sample->biWidth;
|
||||
rFrameHgt = sample->biHeight;
|
||||
rFrameBitsPerPixel = sample->biBitCount;
|
||||
rFramePitch = DWordAligned(rFrameWdt*rFrameBitsPerPixel/8);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AVICloseGrab(PAVISTREAM *ppAviStream,
|
||||
PGETFRAME *ppGetFrame)
|
||||
{
|
||||
if (ppGetFrame && *ppGetFrame)
|
||||
{ AVIStreamGetFrameClose(*ppGetFrame); *ppGetFrame=NULL; }
|
||||
if (ppAviStream && *ppAviStream)
|
||||
{ AVIStreamRelease(*ppAviStream); *ppAviStream=NULL; }
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------
|
||||
|
||||
CStdAVIFile::CStdAVIFile()
|
||||
: pAVIFile(NULL), pStream(NULL), pGetFrame(NULL), pbmi(NULL), hOutDib(NULL), hBitmap(NULL), hDD(NULL), hDC(NULL), hWnd(NULL),
|
||||
pAudioStream(NULL), pAudioData(NULL), iAudioBufferLength(0), pAudioInfo(NULL)
|
||||
{
|
||||
AVIFileInit();
|
||||
}
|
||||
|
||||
CStdAVIFile::~CStdAVIFile()
|
||||
{
|
||||
Clear();
|
||||
AVIFileExit();
|
||||
}
|
||||
|
||||
void CStdAVIFile::Clear()
|
||||
{
|
||||
// free any stuff
|
||||
CloseAudioStream();
|
||||
if (hBitmap) { DeleteObject(hBitmap); hBitmap = NULL; }
|
||||
if (hDD) { DrawDibClose(hDD); hDD = NULL; }
|
||||
if (hDC) { ReleaseDC(hWnd, hDC); hDC = NULL; }
|
||||
if (pGetFrame) { AVIStreamGetFrameClose(pGetFrame); pGetFrame=NULL; }
|
||||
if (pStream) { AVIStreamRelease(pStream); pStream = NULL; }
|
||||
if (pbmi) { delete [] pbmi; pbmi = NULL; }
|
||||
if (pAVIFile) { AVIFileRelease(pAVIFile); pAVIFile = NULL; }
|
||||
sFilename.Clear();
|
||||
}
|
||||
|
||||
bool CStdAVIFile::OpenFile(const char *szFilename, HWND hWnd, int32_t iOutBitDepth)
|
||||
{
|
||||
// clear previous
|
||||
Clear();
|
||||
sFilename.Copy(szFilename);
|
||||
// open the AVI file
|
||||
if (AVIFileOpenW(&pAVIFile, GetWideChar(szFilename), OF_READ, NULL))
|
||||
return false;
|
||||
if (AVIFileGetStream(pAVIFile, &pStream, streamtypeVIDEO, 0))
|
||||
return false;
|
||||
// get stream information
|
||||
AVIStreamInfo(pStream, &StreamInfo, sizeof(AVISTREAMINFO));
|
||||
iWdt = StreamInfo.rcFrame.right-StreamInfo.rcFrame.left;
|
||||
iHgt = StreamInfo.rcFrame.bottom-StreamInfo.rcFrame.top;
|
||||
iFinalFrame = AVIStreamLength(pStream);
|
||||
// some safety
|
||||
if (iWdt<=0 || iHgt<=0 || iFinalFrame<=0) return false;
|
||||
// calculate playback speed
|
||||
iTimePerFrame = AVIStreamSampleToTime(pStream,iFinalFrame)/iFinalFrame;
|
||||
// init buffer bitmap info
|
||||
pbmi = (BITMAPINFO *) new BYTE[sizeof (BITMAPINFO) + 3*sizeof(RGBQUAD)];
|
||||
ZeroMemory(pbmi, sizeof (BITMAPINFO) + 3*sizeof(RGBQUAD));
|
||||
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
pbmi->bmiHeader.biPlanes = 1;
|
||||
pbmi->bmiHeader.biBitCount = iOutBitDepth;
|
||||
pbmi->bmiHeader.biWidth = iWdt;
|
||||
pbmi->bmiHeader.biHeight = -iHgt;
|
||||
pbmi->bmiHeader.biCompression = (iOutBitDepth == 16) ? BI_BITFIELDS : BI_RGB;
|
||||
if (iOutBitDepth == 16)
|
||||
{
|
||||
*(DWORD*)(&(pbmi->bmiColors[2])) = 0x00f;
|
||||
*(DWORD*)(&(pbmi->bmiColors[1])) = 0x0f0;
|
||||
*(DWORD*)(&(pbmi->bmiColors[0])) = 0xf00;
|
||||
}
|
||||
hDC = CreateCompatibleDC(NULL);
|
||||
if (!hDC) return false;
|
||||
hDD = DrawDibOpen();
|
||||
if (!hDD) return false;
|
||||
hBitmap = CreateDIBSection(hDC, pbmi, DIB_RGB_COLORS, (void**)(&pFrameData), NULL, 0);
|
||||
if (!hBitmap) return false;
|
||||
SelectObject(hDC, hBitmap);
|
||||
// create a GetFrame-object
|
||||
pGetFrame=AVIStreamGetFrameOpen(pStream, NULL);
|
||||
if (!pGetFrame) return false;
|
||||
// done, success!
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CStdAVIFile::GetFrameByTime(time_t iTime, int32_t *piFrame)
|
||||
{
|
||||
// safeties
|
||||
if (iTime < 0) return false;
|
||||
if (!piFrame || !iTimePerFrame) return false;
|
||||
// get frame
|
||||
int iFrame = *piFrame = int32_t((iTime + (iTimePerFrame/2)) / iTimePerFrame);
|
||||
return iFrame < iFinalFrame;
|
||||
}
|
||||
|
||||
|
||||
bool CStdAVIFile::GrabFrame(int32_t iFrame, C4Surface *sfc) const
|
||||
{
|
||||
// safeties
|
||||
if (!pGetFrame || !sfc) return false;
|
||||
if (iFrame<0 || iFrame >= iFinalFrame) return false;
|
||||
// grab desired frame
|
||||
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pGetFrame, iFrame);
|
||||
// calculate actual data position
|
||||
BYTE *pImageData = (BYTE *)lpbi + lpbi->biSize + lpbi->biClrUsed*sizeof(RGBQUAD);
|
||||
// draw into buffer bitmap
|
||||
if (!DrawDibDraw (hDD, hDC, 0, 0, iWdt, iHgt, lpbi, pImageData, 0, 0, iWdt, iHgt, 0)) return false;
|
||||
// copy from buffer bitmap into surface - assumes surface is created in the correct size!
|
||||
if (!sfc->Lock()) return false;
|
||||
if (!sfc->CopyBytes(pFrameData)) return false;
|
||||
return !!sfc->Unlock();
|
||||
}
|
||||
|
||||
|
||||
bool CStdAVIFile::OpenAudioStream()
|
||||
{
|
||||
// close previous
|
||||
CloseAudioStream();
|
||||
// open new
|
||||
if (!pAVIFile) return false;
|
||||
if (AVIFileGetStream(pAVIFile, &pAudioStream, streamtypeAUDIO, 0))
|
||||
return false;
|
||||
// get audio stream format
|
||||
if (AVIStreamReadFormat(pAudioStream, AVIStreamStart(pAudioStream), NULL, &iAudioInfoLength)) return false;
|
||||
if (iAudioInfoLength<static_cast<LONG>(sizeof(WAVEFORMAT))) return false;
|
||||
pAudioInfo = (WAVEFORMAT *) new BYTE[iAudioInfoLength];
|
||||
if (AVIStreamReadFormat(pAudioStream, AVIStreamStart(pAudioStream), pAudioInfo, &iAudioInfoLength))
|
||||
{ delete [] pAudioInfo; pAudioInfo=NULL; return false; }
|
||||
// done!
|
||||
return true;
|
||||
}
|
||||
|
||||
BYTE *CStdAVIFile::GetAudioStreamData(size_t *piStreamLength)
|
||||
{
|
||||
// returning the complete audio stream at once here - not very efficient, but easy...
|
||||
// get stream size
|
||||
if (!pAudioInfo) return NULL;
|
||||
if (AVIStreamRead(pAudioStream, 0, AVIStreamLength(pAudioStream), NULL, 0, &iAudioDataLength, NULL)) return NULL;
|
||||
if (iAudioDataLength<=0) return NULL;
|
||||
// make sure current audio data buffer is large enoiugh to hold the data
|
||||
// preceding return data with the RIFF+waveformat structure here
|
||||
uint32_t iHeaderLength = iAudioInfoLength + sizeof(FOURCC) * 4 + 3 * sizeof(uint32_t);
|
||||
LONG iReturnDataLength = iAudioDataLength + iHeaderLength;
|
||||
if (iAudioBufferLength < iReturnDataLength)
|
||||
{
|
||||
delete [] pAudioData;
|
||||
pAudioData = new BYTE[iAudioBufferLength = iReturnDataLength];
|
||||
// build wave file header
|
||||
BYTE *pWrite = pAudioData;
|
||||
*((FOURCC *)pWrite) = mmioFOURCC('R', 'I', 'F', 'F'); pWrite += sizeof(FOURCC);
|
||||
*((uint32_t *)pWrite) = iReturnDataLength - sizeof(FOURCC) - sizeof(uint32_t); pWrite += sizeof(uint32_t);
|
||||
*((FOURCC *)pWrite) = mmioFOURCC('W', 'A', 'V', 'E'); pWrite += sizeof(FOURCC);
|
||||
*((FOURCC *)pWrite) = mmioFOURCC('f', 'm', 't', ' '); pWrite += sizeof(FOURCC);
|
||||
*((uint32_t *)pWrite) = iAudioInfoLength; pWrite += sizeof(uint32_t);
|
||||
memcpy(pWrite, pAudioInfo, iAudioInfoLength); pWrite += iAudioInfoLength;
|
||||
*((FOURCC *)pWrite) = mmioFOURCC('d', 'a', 't', 'a'); pWrite += sizeof(FOURCC);
|
||||
*((uint32_t *)pWrite) = iAudioDataLength;
|
||||
}
|
||||
// get it
|
||||
if (AVIStreamRead(pAudioStream, 0, AVIStreamLength(pAudioStream), pAudioData+iHeaderLength, iAudioDataLength, NULL, NULL)) return NULL;
|
||||
// got the data successfully!
|
||||
*piStreamLength = iReturnDataLength;
|
||||
return pAudioData;
|
||||
}
|
||||
|
||||
void CStdAVIFile::CloseAudioStream()
|
||||
{
|
||||
if (pAudioStream) { AVIStreamRelease(pAudioStream); pAudioStream = NULL; }
|
||||
if (pAudioData) { delete [] pAudioData; pAudioData = NULL; }
|
||||
if (pAudioInfo) { delete [] pAudioInfo; pAudioInfo = NULL; }
|
||||
iAudioBufferLength = 0;
|
||||
}
|
||||
|
||||
#else //HAVE_VFW32
|
||||
#include <StdVideo.h>
|
||||
#include <C4Surface.h>
|
||||
bool AVIOpenOutput(const char *, PAVIFILE *, PAVISTREAM *, int, int) { return false; }
|
||||
bool AVICloseOutput(PAVIFILE *, PAVISTREAM *) { return true; }
|
||||
bool AVIPutFrame(PAVISTREAM, long, void *, long, void *, long) { return false; }
|
||||
bool AVIOpenGrab(const char *, PAVISTREAM *, PGETFRAME *, int &, int &, int &, int &, int &) { return false; }
|
||||
void AVICloseGrab(PAVISTREAM *, PGETFRAME *) { }
|
||||
CStdAVIFile::CStdAVIFile() { }
|
||||
CStdAVIFile::~CStdAVIFile() { }
|
||||
void CStdAVIFile::Clear() { }
|
||||
bool CStdAVIFile::OpenFile(const char *, HWND, int32_t) { return false; }
|
||||
bool CStdAVIFile::GetFrameByTime(time_t, int32_t *) { return false; }
|
||||
bool CStdAVIFile::GrabFrame(int32_t, C4Surface *) const { return false; }
|
||||
bool CStdAVIFile::OpenAudioStream() { return false; }
|
||||
BYTE *CStdAVIFile::GetAudioStreamData(size_t *) { return NULL; }
|
||||
void CStdAVIFile::CloseAudioStream() { }
|
||||
#endif // HAVE_VFW32
|
||||
|
||||
#endif // _WIN32
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 1998-2000, Matthes Bender
|
||||
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
|
||||
* Copyright (c) 2013, The OpenClonk Team and contributors
|
||||
*
|
||||
* Distributed under the terms of the ISC license; see accompanying file
|
||||
* "COPYING" for details.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
||||
* See accompanying file "TRADEMARK" for details.
|
||||
*
|
||||
* To redistribute this file separately, substitute the full license texts
|
||||
* for the above references.
|
||||
*/
|
||||
|
||||
/* Some functions to help with loading and saving AVI files using Video for Windows */
|
||||
|
||||
#ifndef INC_STDVIDEO
|
||||
#define INC_STDVIDEO
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
|
||||
#include <C4windowswrapper.h> // some vfw.h versions do not compile without this
|
||||
#undef MK_ALT
|
||||
#include <mmsystem.h>
|
||||
#include <vfw.h>
|
||||
#include <io.h>
|
||||
#include "StdBuf.h"
|
||||
|
||||
bool AVIOpenGrab(const char *szFilename,
|
||||
PAVISTREAM *ppAviStream,
|
||||
PGETFRAME *ppGetFrame,
|
||||
int &rAviLength, int &rFrameWdt, int &rFrameHgt,
|
||||
int &rFrameBitsPerPixel, int &rFramePitch);
|
||||
|
||||
void AVICloseGrab(PAVISTREAM *ppAviStream,
|
||||
PGETFRAME *ppGetFrame);
|
||||
|
||||
bool AVIOpenOutput(const char *szFilename,
|
||||
PAVIFILE *ppAviFile,
|
||||
PAVISTREAM *ppAviStream,
|
||||
int iWidth, int iHeight);
|
||||
|
||||
bool AVICloseOutput(PAVIFILE *ppAviFile,
|
||||
PAVISTREAM *ppAviStream);
|
||||
|
||||
bool AVIPutFrame(PAVISTREAM pAviStream,
|
||||
long lFrame,
|
||||
void *lpInfo, long lInfoSize,
|
||||
void *lpData, long lDataSize);
|
||||
|
||||
|
||||
// AVI file reading class
|
||||
class CStdAVIFile
|
||||
{
|
||||
private:
|
||||
// file data
|
||||
StdStrBuf sFilename;
|
||||
PAVIFILE pAVIFile;
|
||||
|
||||
// video data
|
||||
AVISTREAMINFO StreamInfo;
|
||||
PAVISTREAM pStream;
|
||||
PGETFRAME pGetFrame;
|
||||
|
||||
// video processing helpers
|
||||
BITMAPINFO *pbmi;
|
||||
HDRAWDIB hOutDib;
|
||||
HBITMAP hBitmap;
|
||||
HDRAWDIB hDD;
|
||||
HDC hDC;
|
||||
BYTE *pFrameData;
|
||||
HWND hWnd;
|
||||
|
||||
// audio data
|
||||
PAVISTREAM pAudioStream;
|
||||
BYTE *pAudioData;
|
||||
LONG iAudioDataLength, iAudioBufferLength;
|
||||
WAVEFORMAT *pAudioInfo;
|
||||
LONG iAudioInfoLength;
|
||||
|
||||
// frame data
|
||||
int32_t iFinalFrame, iWdt, iHgt;
|
||||
time_t iTimePerFrame; // [ms/frame]
|
||||
|
||||
public:
|
||||
CStdAVIFile();
|
||||
~CStdAVIFile();
|
||||
|
||||
void Clear();
|
||||
bool OpenFile(const char *szFilename, HWND hWnd, int32_t iOutBitDepth);
|
||||
|
||||
int32_t GetWdt() const { return iWdt; }
|
||||
int32_t GetHgt() const { return iHgt; }
|
||||
|
||||
// get desired frame from time offset to video start - return false if past video length
|
||||
bool GetFrameByTime(time_t iTime, int32_t *piFrame);
|
||||
|
||||
// dump RGBa-data for specified frame
|
||||
bool GrabFrame(int32_t iFrame, class C4Surface *sfc) const;
|
||||
|
||||
// getting audio data
|
||||
bool OpenAudioStream();
|
||||
BYTE *GetAudioStreamData(size_t *piStreamLength);
|
||||
void CloseAudioStream();
|
||||
};
|
||||
#endif //_WIN32
|
||||
|
||||
#endif //INC_STDVIDEO
|
Loading…
Reference in New Issue