forked from Mirrors/openclonk
remove video playback feature
parent
b5d0af513a
commit
41a33999cd
|
@ -504,8 +504,6 @@ set(OC_CLONK_SOURCES
|
|||
src/platform/C4SoundSystem.h
|
||||
src/platform/C4Video.cpp
|
||||
src/platform/C4Video.h
|
||||
src/platform/C4VideoPlayback.cpp
|
||||
src/platform/C4VideoPlayback.h
|
||||
src/platform/C4Window.h
|
||||
src/platform/C4windowswrapper.h
|
||||
src/platform/GetTime.cpp
|
||||
|
|
|
@ -468,8 +468,6 @@ src/platform/C4SoundSystem.cpp \
|
|||
src/platform/C4SoundSystem.h \
|
||||
src/platform/C4Video.cpp \
|
||||
src/platform/C4Video.h \
|
||||
src/platform/C4VideoPlayback.cpp \
|
||||
src/platform/C4VideoPlayback.h \
|
||||
src/platform/C4Window.h \
|
||||
src/platform/C4windowswrapper.h \
|
||||
src/platform/PlatformAbstraction.cpp \
|
||||
|
|
|
@ -572,7 +572,6 @@ void C4Game::Clear()
|
|||
Control.Clear();
|
||||
|
||||
// Clear
|
||||
VideoPlayer.Clear();
|
||||
Scoreboard.Clear();
|
||||
MouseControl.Clear();
|
||||
Players.Clear();
|
||||
|
@ -2019,10 +2018,6 @@ bool C4Game::InitGame(C4Group &hGroup, bool fLoadSection, bool fLoadSky, C4Value
|
|||
// Materials
|
||||
if (!InitMaterialTexture())
|
||||
{ LogFatal(LoadResStr("IDS_PRC_MATERROR")); return false; }
|
||||
SetInitProgress(59);
|
||||
|
||||
// Videos
|
||||
if (!VideoPlayer.PreloadVideos(hGroup)) return false;
|
||||
SetInitProgress(60);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <C4PathFinder.h>
|
||||
#include <C4Extra.h>
|
||||
#include "C4Scoreboard.h"
|
||||
#include <C4VideoPlayback.h>
|
||||
#include <C4PlayerControl.h>
|
||||
|
||||
class C4Game
|
||||
|
@ -84,7 +83,6 @@ public:
|
|||
C4PlayerControlDefs PlayerControlDefs;
|
||||
C4PlayerControlAssignmentSets PlayerControlUserAssignmentSets, PlayerControlDefaultAssignmentSets;
|
||||
C4Scoreboard Scoreboard;
|
||||
C4VideoPlayer VideoPlayer;
|
||||
C4Network2Stats *pNetworkStatistics; // may be NULL if no statistics are recorded
|
||||
C4KeyboardInput &KeyboardInput;
|
||||
C4FileMonitor *pFileMonitor;
|
||||
|
|
|
@ -2087,14 +2087,6 @@ static long FnActivateGameGoalMenu(C4PropList * _this, long iPlayer)
|
|||
return pPlr->Menu.ActivateGoals(pPlr->Number, pPlr->LocalControl && !::Control.isReplay());
|
||||
}
|
||||
|
||||
static bool FnPlayVideo(C4PropList * _this, C4String *pFilename)
|
||||
{
|
||||
// filename must be valid
|
||||
if (!pFilename || !pFilename->GetCStr()) return false;
|
||||
// play it!
|
||||
return Game.VideoPlayer.PlayVideo(pFilename->GetCStr());
|
||||
}
|
||||
|
||||
static bool FnCustomMessage(C4PropList * _this, C4String *pMsg, C4Object *pObj, Nillable<long> iOwner, long iOffX, long iOffY, long dwClr, C4ID idDeco, C4PropList *pSrc, long dwFlags, long iHSize)
|
||||
{
|
||||
// safeties
|
||||
|
@ -2426,7 +2418,6 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine)
|
|||
AddFunc(pEngine, "HideSettlementScoreInEvaluation", FnHideSettlementScoreInEvaluation);
|
||||
AddFunc(pEngine, "ExtractMaterialAmount", FnExtractMaterialAmount);
|
||||
AddFunc(pEngine, "GetEffectCount", FnGetEffectCount);
|
||||
AddFunc(pEngine, "PlayVideo", FnPlayVideo, false);
|
||||
AddFunc(pEngine, "CustomMessage", FnCustomMessage);
|
||||
AddFunc(pEngine, "PauseGame", FnPauseGame, false);
|
||||
AddFunc(pEngine, "PathFree", FnPathFree);
|
||||
|
|
|
@ -1,364 +0,0 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 2006 Sven Eberhardt
|
||||
* Copyright (c) 2007 Günther Brammer
|
||||
* Copyright (c) 2006-2009, RedWolf Design GmbH, http://www.clonk.de
|
||||
*
|
||||
* Portions might be copyrighted by other authors who have contributed
|
||||
* to OpenClonk.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* See isc_license.txt for full license and disclaimer.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender.
|
||||
* See clonk_trademark_license.txt for full license.
|
||||
*/
|
||||
// InGame sequence video playback support
|
||||
|
||||
#include <C4Include.h>
|
||||
#include <C4VideoPlayback.h>
|
||||
|
||||
#include <C4FullScreen.h>
|
||||
#include <C4Game.h>
|
||||
#include "C4Gui.h"
|
||||
#include <C4Log.h>
|
||||
|
||||
#include <StdVideo.h>
|
||||
|
||||
#ifdef HAVE_LIBSMPEG
|
||||
#include <smpeg/smpeg.h>
|
||||
#include <SDL.h>
|
||||
#include <SDL_mixer.h>
|
||||
#endif // HAVE_LIBSMPEG
|
||||
|
||||
|
||||
// playback dialog
|
||||
class C4VideoShowDialog : public C4GUI::FullscreenDialog
|
||||
{
|
||||
private:
|
||||
#ifdef USE_WIN32_WINDOWS
|
||||
CStdAVIFile AVIFile;
|
||||
C4SoundEffect *pAudioTrack;
|
||||
#endif
|
||||
#ifdef HAVE_LIBSDL_MIXER
|
||||
SMPEG * mpeg;
|
||||
SMPEG_Info * mpeg_info;
|
||||
SDL_Surface * surface;
|
||||
#endif
|
||||
C4FacetSurface fctBuffer;
|
||||
time_t iStartFrameTime;
|
||||
|
||||
protected:
|
||||
virtual int32_t GetZOrdering() { return C4GUI_Z_VIDEO; }
|
||||
virtual bool IsExclusiveDialog() { return true; }
|
||||
|
||||
void VideoDone(); // mark video done
|
||||
|
||||
public:
|
||||
C4VideoShowDialog() : C4GUI::FullscreenDialog(NULL, NULL)
|
||||
#ifdef USE_WIN32_WINDOWS
|
||||
, pAudioTrack(NULL)
|
||||
#endif
|
||||
#ifdef HAVE_LIBSDL_MIXER
|
||||
, mpeg(0)
|
||||
, mpeg_info(0)
|
||||
, surface(0)
|
||||
#endif
|
||||
{}
|
||||
~C4VideoShowDialog();
|
||||
|
||||
bool LoadVideo(C4VideoFile *pVideoFile);
|
||||
|
||||
virtual void DrawElement(C4TargetFacet &cgo); // draw current video frame
|
||||
};
|
||||
|
||||
|
||||
void C4VideoFile::Clear()
|
||||
{
|
||||
if (sFilename.getLength())
|
||||
{
|
||||
if (fIsTemp) if (!EraseFile(sFilename.getData()))
|
||||
{
|
||||
LogF("C4VideoFile::Clear: Error deleting temporary video file %s", (const char *) sFilename.getData());
|
||||
}
|
||||
sFilename.Clear();
|
||||
}
|
||||
fIsTemp = false;
|
||||
}
|
||||
|
||||
bool C4VideoFile::Load(const char *szFilename, bool fTemp)
|
||||
{
|
||||
// clear previous
|
||||
Clear();
|
||||
// some simple sanity check
|
||||
if (!FileExists(szFilename)) return false;
|
||||
// simply link to file
|
||||
sFilename.Copy(szFilename);
|
||||
fIsTemp = fTemp;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C4VideoFile::Load(class C4Group &hGrp, const char *szFilename)
|
||||
{
|
||||
// unpacked group?
|
||||
if (!hGrp.IsPacked())
|
||||
{
|
||||
// then direct file registration is possible
|
||||
StdStrBuf sPath; sPath.Take(hGrp.GetFullName());
|
||||
sFilename.AppendChar(DirectorySeparator);
|
||||
sFilename.Append(szFilename);
|
||||
return Load(sPath.getData());
|
||||
}
|
||||
// packed group: Extract to temp space
|
||||
char szTempFn[_MAX_PATH+1];
|
||||
SCopy(Config.AtTempPath(::GetFilename(szFilename)), szTempFn, _MAX_PATH);
|
||||
MakeTempFilename(szTempFn);
|
||||
if (!hGrp.ExtractEntry(szFilename, szTempFn))
|
||||
return false;
|
||||
return Load(szTempFn, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// C4VideoShowDialog
|
||||
|
||||
bool C4VideoShowDialog::LoadVideo(C4VideoFile *pVideoFile)
|
||||
{
|
||||
#ifdef USE_WIN32_WINDOWS
|
||||
// load video file
|
||||
if (!AVIFile.OpenFile(pVideoFile->GetFilename(), FullScreen.hWindow, pDraw->GetByteCnt()*8)) return false;
|
||||
// prepare surface for display
|
||||
if (!fctBuffer.Create(AVIFile.GetWdt(), AVIFile.GetHgt(), C4FCT_Full, C4FCT_Full)) return false;
|
||||
iStartFrameTime = 0; // no frame shown yet
|
||||
// play audio
|
||||
if (Config.Sound.RXSound && AVIFile.OpenAudioStream())
|
||||
{
|
||||
size_t iAudioDataSize=0;
|
||||
BYTE *pAudioData = AVIFile.GetAudioStreamData(&iAudioDataSize);
|
||||
if (pAudioData)
|
||||
{
|
||||
if (pAudioTrack) delete pAudioTrack;
|
||||
pAudioTrack = new C4SoundEffect();
|
||||
if (pAudioTrack->Load(pAudioData, iAudioDataSize, false))
|
||||
{
|
||||
C4SoundInstance *pSoundInst = pAudioTrack->New();
|
||||
if (pSoundInst) pSoundInst->Start();
|
||||
}
|
||||
}
|
||||
AVIFile.CloseAudioStream();
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
#ifdef HAVE_LIBSMPEG
|
||||
// FIXME
|
||||
return false;
|
||||
mpeg_info = new SMPEG_Info;
|
||||
mpeg = SMPEG_new(pVideoFile->GetFilename(), mpeg_info, 0);
|
||||
if (SMPEG_error(mpeg))
|
||||
{
|
||||
LogF("smpeg: %s", SMPEG_error(mpeg));
|
||||
return false;
|
||||
}
|
||||
if (!fctBuffer.Create(mpeg_info->width, mpeg_info->height, C4FCT_Full, C4FCT_Full)) return false;
|
||||
surface = SDL_AllocSurface(SDL_SWSURFACE,
|
||||
mpeg_info->width,
|
||||
mpeg_info->height,
|
||||
32,
|
||||
0x000000FF,
|
||||
0x0000FF00,
|
||||
0x00FF0000,
|
||||
0xFF000000);
|
||||
if (!surface)
|
||||
{
|
||||
LogF("smpeg: %s", SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
SMPEG_setdisplay(mpeg, surface, NULL, /*glmpeg_update*/NULL);
|
||||
|
||||
/* Play the movie, using SDL_mixer for audio */
|
||||
//SMPEG_enableaudio(mpeg, 0);
|
||||
SDL_AudioSpec audiofmt;
|
||||
Uint16 format;
|
||||
int freq, channels;
|
||||
|
||||
/* Tell SMPEG what the audio format is */
|
||||
Mix_QuerySpec(&freq, &format, &channels);
|
||||
audiofmt.format = format;
|
||||
audiofmt.freq = freq;
|
||||
audiofmt.channels = channels;
|
||||
SMPEG_actualSpec(mpeg, &audiofmt);
|
||||
|
||||
SMPEG_play(mpeg);
|
||||
/* Hook in the MPEG music mixer */
|
||||
Mix_HookMusic(SMPEG_playAudioSDL, mpeg);
|
||||
//SMPEG_enableaudio(mpeg, 1);
|
||||
|
||||
return true;
|
||||
#endif // HAVE_LIBSMPEG
|
||||
#endif // _WIN32
|
||||
return false;
|
||||
}
|
||||
|
||||
C4VideoShowDialog::~C4VideoShowDialog()
|
||||
{
|
||||
#ifdef USE_WIN32_WINDOWS
|
||||
if (pAudioTrack) delete pAudioTrack;
|
||||
#else
|
||||
#ifdef HAVE_LIBSMPEG
|
||||
// FIXME
|
||||
return;
|
||||
/* Stop the movie and unhook SMPEG from the mixer */
|
||||
SMPEG_stop(mpeg);
|
||||
SMPEG_delete(mpeg);
|
||||
Mix_HookMusic(NULL, NULL);
|
||||
SDL_FreeSurface(surface);
|
||||
delete mpeg_info;
|
||||
#endif // HAVE_LIBSMPEG
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void C4VideoShowDialog::VideoDone()
|
||||
{
|
||||
// finished playback
|
||||
if (IsShown()) Close(true);
|
||||
}
|
||||
|
||||
void C4VideoShowDialog::DrawElement(C4TargetFacet &cgo)
|
||||
{
|
||||
// draw current video frame
|
||||
#ifdef USE_WIN32_WINDOWS
|
||||
// get frame to be drawn
|
||||
time_t iCurrFrameTime = GetTime();
|
||||
int32_t iGetFrame;
|
||||
if (!iStartFrameTime) iStartFrameTime = iCurrFrameTime;
|
||||
if (!AVIFile.GetFrameByTime(iCurrFrameTime - iStartFrameTime, &iGetFrame))
|
||||
{
|
||||
// no frame available: Video playback done!
|
||||
// 2do: This will always show the last frame two gfx frames?
|
||||
VideoDone();
|
||||
}
|
||||
else
|
||||
{
|
||||
// get available frame
|
||||
AVIFile.GrabFrame(iGetFrame, &(fctBuffer.GetFace()));
|
||||
}
|
||||
// draw the found frame
|
||||
fctBuffer.Draw(cgo, false);
|
||||
#else
|
||||
#ifdef HAVE_LIBSMPEG
|
||||
// FIXME
|
||||
return;
|
||||
C4Surface * sfc = &fctBuffer.GetFace();
|
||||
sfc->Lock();
|
||||
sfc->CopyBytes((BYTE*)surface->pixels);
|
||||
sfc->Unlock();
|
||||
fctBuffer.Draw(cgo, false);
|
||||
if (SMPEG_status(mpeg) != SMPEG_PLAYING)
|
||||
VideoDone();
|
||||
#endif // HAVE_LIBSMPEG
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
|
||||
// C4VideoPlayer
|
||||
|
||||
void C4VideoPlayer::Clear()
|
||||
{
|
||||
// delete all loaded videos
|
||||
C4VideoFile *pDelFile;
|
||||
while ((pDelFile = pFirstVideo))
|
||||
{
|
||||
pFirstVideo = pDelFile->GetNext();
|
||||
delete pDelFile;
|
||||
}
|
||||
}
|
||||
|
||||
bool C4VideoPlayer::PreloadVideos(class C4Group &rFromGroup)
|
||||
{
|
||||
// preload all videos from group file
|
||||
rFromGroup.ResetSearch();
|
||||
char szFilename[_MAX_PATH+1];
|
||||
int32_t iNumLoaded = 0; bool fAnyLoaded=false;
|
||||
while (rFromGroup.FindNextEntry(C4CFN_AnimationFiles, szFilename))
|
||||
{
|
||||
if (!fAnyLoaded)
|
||||
{
|
||||
// log message: Only if there are videos, because in 99.99% of the cases, there are none
|
||||
LogF(LoadResStr("IDS_PRC_PRELOADVIDEOS"), rFromGroup.GetName());
|
||||
fAnyLoaded = true;
|
||||
}
|
||||
C4VideoFile *pVideoFile = new C4VideoFile();
|
||||
if (!pVideoFile->Load(rFromGroup, szFilename))
|
||||
{
|
||||
LogF("C4VideoPlayer::PreloadVideos: Error preloading video %s from group %s.", szFilename, rFromGroup.GetFullName().getData());
|
||||
delete pVideoFile;
|
||||
continue;
|
||||
}
|
||||
if (pFirstVideo) pVideoFile->SetNext(pFirstVideo);
|
||||
pFirstVideo = pVideoFile;
|
||||
++iNumLoaded;
|
||||
}
|
||||
// done loading
|
||||
return true;
|
||||
}
|
||||
|
||||
bool C4VideoPlayer::PlayVideo(const char *szVideoFilename)
|
||||
{
|
||||
// video speicifed by filename - uses preload database if possible; otherwise gets video from root video collection
|
||||
// search video file in loaded list
|
||||
C4VideoFile *pVidFile;
|
||||
for (pVidFile = pFirstVideo; pVidFile; pVidFile = pVidFile->GetNext())
|
||||
if (ItemIdentical(pVidFile->GetFilename(), szVideoFilename))
|
||||
break;
|
||||
bool fTempLoaded = false;
|
||||
if (!pVidFile)
|
||||
{
|
||||
// video not found: Try loading it from game root
|
||||
pVidFile = new C4VideoFile();
|
||||
if (SCharPos('/', szVideoFilename)>=0 || SCharPos('\\', szVideoFilename)>=0)
|
||||
{
|
||||
// subfolders involved: UseC4Group to load the video
|
||||
char szParentPath[_MAX_PATH+1];
|
||||
if (!GetParentPath(szVideoFilename, szParentPath)) { delete pVidFile; return false; }
|
||||
C4Group Grp;
|
||||
if (!Grp.Open(szParentPath)) { delete pVidFile; return false; }
|
||||
if (!pVidFile->Load(Grp, GetFilename(szVideoFilename))) { delete pVidFile; return false; }
|
||||
}
|
||||
else
|
||||
{
|
||||
// Direct filename in Clonk directory
|
||||
if (!pVidFile->Load(szVideoFilename)) { delete pVidFile; return false; }
|
||||
}
|
||||
fTempLoaded = true;
|
||||
}
|
||||
// OK, play that video
|
||||
bool fSuccess = PlayVideo(pVidFile);
|
||||
// cleanup
|
||||
if (fTempLoaded) delete pVidFile;
|
||||
return fSuccess;
|
||||
}
|
||||
|
||||
bool C4VideoPlayer::PlayVideo(C4VideoFile *pVideoFile)
|
||||
{
|
||||
// safety
|
||||
if (!pVideoFile) return false;
|
||||
// plays the specified video and returns when finished or skipped by user (blocking call)
|
||||
// cannot play in console mode
|
||||
if (!FullScreen.Active) return false;
|
||||
// videos are played in a fullscreen GUI dialog
|
||||
C4VideoShowDialog *pVideoDlg = new C4VideoShowDialog();
|
||||
if (!pVideoDlg->LoadVideo(pVideoFile))
|
||||
{
|
||||
DebugLogF("Error playing video file: %s", pVideoFile->GetFilename());
|
||||
delete pVideoDlg;
|
||||
return false;
|
||||
}
|
||||
++Game.HaltCount;
|
||||
::pGUI->ShowModalDlg(pVideoDlg, true); // ignore result; even an aborted video was shown successfully
|
||||
--Game.HaltCount;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 2006 Sven Eberhardt
|
||||
* Copyright (c) 2007 Günther Brammer
|
||||
* Copyright (c) 2006-2009, RedWolf Design GmbH, http://www.clonk.de
|
||||
*
|
||||
* Portions might be copyrighted by other authors who have contributed
|
||||
* to OpenClonk.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* See isc_license.txt for full license and disclaimer.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender.
|
||||
* See clonk_trademark_license.txt for full license.
|
||||
*/
|
||||
// InGame sequence video playback support
|
||||
|
||||
#ifndef INC_C4VideoPlayback
|
||||
#define INC_C4VideoPlayback
|
||||
|
||||
typedef struct _SMPEG SMPEG;
|
||||
typedef struct _SMPEG_Info SMPEG_Info;
|
||||
typedef struct SDL_Surface SDL_Surface;
|
||||
|
||||
// a preloaded video file
|
||||
class C4VideoFile
|
||||
{
|
||||
private:
|
||||
StdStrBuf sFilename; // path to filename for avi file
|
||||
bool fIsTemp; // if set, the file is temporary will be deleted upon destruction of this object
|
||||
C4VideoFile *pNext;
|
||||
|
||||
public:
|
||||
C4VideoFile() : fIsTemp(false), pNext(NULL) {}
|
||||
~C4VideoFile() { Clear(); }
|
||||
|
||||
void Clear();
|
||||
|
||||
bool Load(const char *szFilename, bool fTemp=false); // create from file
|
||||
bool Load(class C4Group &hGrp, const char *szFilename); // create from group: Extract to temp file if group is packed
|
||||
|
||||
C4VideoFile *GetNext() const { return pNext; }
|
||||
const char *GetFilename() const { return sFilename.getData(); }
|
||||
|
||||
void SetNext(C4VideoFile *pNewNext) { pNext = pNewNext; }
|
||||
};
|
||||
|
||||
// main playback class (C4Game member)
|
||||
class C4VideoPlayer
|
||||
{
|
||||
private:
|
||||
C4VideoFile *pFirstVideo;
|
||||
|
||||
// plays the specified video and returns when finished or skipped by user (blocking call)
|
||||
bool PlayVideo(C4VideoFile *pVideoFile);
|
||||
|
||||
public:
|
||||
C4VideoPlayer() : pFirstVideo(NULL) {}
|
||||
~C4VideoPlayer() { Clear(); }
|
||||
|
||||
// delete all loaded videos
|
||||
void Clear();
|
||||
|
||||
// preload videos from file
|
||||
bool PreloadVideos(class C4Group &rFromGroup);
|
||||
|
||||
// plays the specified video and returns when finished or skipped by user (blocking call)
|
||||
// video speicifed by filename - uses preload database if possible; otherwise gets video from root video collection
|
||||
bool PlayVideo(const char *szVideoFilename);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue