Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AGS 4: non-blocking video playback #2338

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions Editor/AGS.Editor/Resources/agsdefns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2659,6 +2659,51 @@ builtin managed struct Joystick {
};
#endif
#ifdef SCRIPT_API_v400
enum PlaybackState {
ePlaybackOn = 2,
ePlaybackPaused = 3,
ePlaybackStopped = 4
};
builtin managed struct VideoPlayer {
import static VideoPlayer* Open(const string filename, bool autoPlay=true, RepeatStyle=eOnce);
/// Starts or resumes the playback.
import void Play();
/// Pauses the playback.
import void Pause();
/// Advances video by 1 frame, may be called when the video is paused.
import void NextFrame();
/// Changes playback to continue from the specified frame; returns new position or -1 on error.
import int SeekFrame(int frame);
/// Changes playback to continue from the specified position in milliseconds; returns new position or -1 on error.
import int SeekMs(int position);
/// Stops the video completely.
import void Stop();
/// Gets current frame index.
import readonly attribute int Frame;
/// Gets total number of frames in this video.
import readonly attribute int FrameCount;
/// Gets this video's framerate (number of frames per second).
import readonly attribute float FrameRate;
/// Gets the number of sprite this video renders to.
import readonly attribute int Graphic;
/// The length of the currently playing video, in milliseconds.
import readonly attribute int LengthMs;
/// Gets/sets whether the video should loop.
import attribute bool Looping;
/// The current playback position, in milliseconds.
import readonly attribute int PositionMs;
/// The speed of playing (1.0 is default).
import attribute float Speed;
/// Gets the current playback state (playing, paused, etc).
import readonly attribute PlaybackState State;
/// The volume of this video's sound, from 0 to 100.
import attribute int Volume;
};
#endif
import ColorType palette[PALETTE_SIZE];
import Mouse mouse;
Expand Down
6 changes: 6 additions & 0 deletions Engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ target_sources(engine
ac/dynobj/scriptsystem.cpp
ac/dynobj/scriptuserobject.cpp
ac/dynobj/scriptuserobject.h
ac/dynobj/scriptvideoplayer.cpp
ac/dynobj/scriptvideoplayer.h
ac/dynobj/scriptviewframe.cpp
ac/dynobj/scriptviewframe.h
ac/dynobj/scriptviewport.cpp
Expand Down Expand Up @@ -248,6 +250,7 @@ target_sources(engine
ac/timer.h
ac/translation.cpp
ac/translation.h
ac/video_script.cpp
ac/viewframe.cpp
ac/viewframe.h
ac/viewport_script.cpp
Expand Down Expand Up @@ -375,6 +378,8 @@ target_sources(engine
media/video/theora_player.h
media/video/video.cpp
media/video/video.h
media/video/video_core.cpp
media/video/video_core.h
media/video/videoplayer.cpp
media/video/videoplayer.h
platform/base/agsplatformdriver.cpp
Expand Down Expand Up @@ -415,6 +420,7 @@ target_sources(engine
util/library_posix.h
util/sdl2_util.h
util/sdl2_util.cpp
util/threading.h

platform/windows/acplwin.cpp
platform/windows/debug/namedpipesagsdebugger.cpp
Expand Down
51 changes: 51 additions & 0 deletions Engine/ac/dynobj/scriptvideoplayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//=============================================================================
//
// Adventure Game Studio (AGS)
//
// Copyright (C) 1999-2011 Chris Jones and 2011-2024 various contributors
// The full list of copyright holders can be found in the Copyright.txt
// file, which is part of this source code distribution.
//
// The AGS source code is provided under the Artistic License 2.0.
// A copy of this license can be found in the file License.txt and at
// https://opensource.org/license/artistic-2-0/
//
//=============================================================================
#include "ac/dynobj/scriptvideoplayer.h"
#include "ac/dynobj/dynobj_manager.h"
#include "media/video/video.h"
#include "util/stream.h"

using namespace AGS::Common;

const char *ScriptVideoPlayer::GetType()
{
return "VideoPlayer";
}

int ScriptVideoPlayer::Dispose(void* /*address*/, bool /*force*/)
{
if (_id >= 0)
{
video_stop(_id);
}

delete this;
return 1;
}

size_t ScriptVideoPlayer::CalcSerializeSize(const void* /*address*/)
{
return sizeof(int32_t);
}

void ScriptVideoPlayer::Serialize(const void* /*address*/, Stream *out)
{
out->WriteInt32(_id);
}

void ScriptVideoPlayer::Unserialize(int index, Stream *in, size_t /*data_sz*/)
{
_id = in->ReadInt32();
ccRegisterUnserializedObject(index, this, this);
}
41 changes: 41 additions & 0 deletions Engine/ac/dynobj/scriptvideoplayer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//=============================================================================
//
// Adventure Game Studio (AGS)
//
// Copyright (C) 1999-2011 Chris Jones and 2011-2024 various contributors
// The full list of copyright holders can be found in the Copyright.txt
// file, which is part of this source code distribution.
//
// The AGS source code is provided under the Artistic License 2.0.
// A copy of this license can be found in the file License.txt and at
// https://opensource.org/license/artistic-2-0/
//
//=============================================================================
#ifndef __AC_SCRIPTVIDEOPLAYER_H
#define __AC_SCRIPTVIDEOPLAYER_H

#include "ac/dynobj/cc_agsdynamicobject.h"

struct ScriptVideoPlayer final : AGSCCDynamicObject
{
public:
ScriptVideoPlayer(int id) : _id(id) {}
// Get videoplayer's index; negative means the video was removed
int GetID() const { return _id; }
// Reset videoplayer's index to indicate that this reference is no longer valid
void Invalidate() { _id = -1; }

const char *GetType() override;
int Dispose(void *address, bool force) override;
void Unserialize(int index, AGS::Common::Stream *in, size_t data_sz) override;

private:
// Calculate and return required space for serialization, in bytes
size_t CalcSerializeSize(const void *address) override;
// Write object data into the provided stream
void Serialize(const void *address, AGS::Common::Stream *out) override;

int _id = -1; // index of videoplayer in the video subsystem
};

#endif // __AC_SCRIPTVIDEOPLAYER_H
1 change: 1 addition & 0 deletions Engine/ac/global_video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "debug/debugger.h"
#include "debug/debug_log.h"
#include "media/video/video.h"
#include "media/video/videoplayer.h" // for flags

using namespace AGS::Common;
using namespace AGS::Engine;
Expand Down
2 changes: 2 additions & 0 deletions Engine/ac/timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "platform/base/agsplatformdriver.h"
#if defined(AGS_DISABLE_THREADS)
#include "media/audio/audio_core.h"
#include "media/video/video_core.h"
#endif
#if AGS_PLATFORM_OS_EMSCRIPTEN
#include "SDL.h"
Expand Down Expand Up @@ -71,6 +72,7 @@ void WaitForNextFrame()
// Do the last polls on this frame, if necessary
#if defined(AGS_DISABLE_THREADS)
audio_core_entry_poll();
video_core_entry_poll();
#endif

const auto now = AGS_Clock::now();
Expand Down
Loading
Loading