Video playback (#1625)

* Work

* Work

* Update Video.cpp

* Update Video.cpp

* Update Video.cpp

* Update Video.cpp

* Update Video.cpp

* Working playback

* Update Video.cpp

* Cleanups

* Additions

* Update Video.cpp

* Formatting

* Correct pausing/resuming

* Remove .mov extension, as it's not supported

* Use vector instead of array

* Implement SetIntroVideoPath

* Swap intro image and intro video to better reflect original legal sequence

* Update Gameflow.lua

* Simplify synchronization with VLC thread

* Use Vector2i for sizes, only fetch video dimensions once

* Rename callbacks, move logging callback to a class

* Update Video.cpp

* Update CHANGELOG.md

* Removed empty OnDisplayFrame event

* Rename

* Stop video player if user pressed Alt+F4

* Allow background video playback

* Update Video.cpp

* Update Video.cpp

* Fixed init errors

* Restore .mov default extension for video playback

* Update RendererDraw2D.cpp

* Add video streaming for rectangular faces of room geometry

* Remove magic and use normalized UVs instead

* Use VIDEO_SPRITE_ID instead of NO_VALUE

* Added more scripting API functions for video playback

* Correct variable names

* Shorten notification

* Add GetVideoDominantColor

* Do proper cleanup when alt+F4ing during video playback

* Change game loop deinit to avoid several issues with cleaning up

* Organise `VideoHandler` class

* Randomize glow angle

* Update comment

* Update Video.cpp

* Update Video.cpp

* Fix issues with frame drops in exclusive mode

* Optimize CPU usage in exclusive mode

---------

Co-authored-by: Sezz <sezzary@outlook.com>
This commit is contained in:
Lwmte 2025-04-20 22:06:07 +03:00 committed by GitHub
parent 9b6bf198bb
commit cb23823e64
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
65 changed files with 8551 additions and 148 deletions

View file

@ -5,6 +5,9 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
## [Version 1.8.2] ## [Version 1.8.2]
## New features
* Added video playback support.
### Bug fixes ### Bug fixes
* Fixed crashes when shooting, if gunflash or gunshell objects are not present in a level. * Fixed crashes when shooting, if gunflash or gunshell objects are not present in a level.
* Fixed Teleporter object. * Fixed Teleporter object.
@ -20,6 +23,8 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Added muzzle glow effect for firearms. * Added muzzle glow effect for firearms.
### Lua API changes ### Lua API changes
* Added `View.PlayVideoFile` function to play videos.
* Added `Flow.SetIntroVideoPath` function to specify intro video.
* Added `muzzleGlow` and `muzzleOffset` parameters to weapon settings. * Added `muzzleGlow` and `muzzleOffset` parameters to weapon settings.
* Added ability to use gunflash parameters for all weapons in weapon settings. * Added ability to use gunflash parameters for all weapons in weapon settings.
* Fixed `Moveable.GetJointPosition` not returning correct results if moveable is invisible or not rendered. * Fixed `Moveable.GetJointPosition` not returning correct results if moveable is invisible or not rendered.

View file

@ -132,6 +132,10 @@ scripts too.</p>
<td class="summary">Image to show when loading the game.</td> <td class="summary">Image to show when loading the game.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#SetIntroVideoPath">SetIntroVideoPath(path)</a></td>
<td class="summary">Video to show when loading the game.</td>
</tr>
<tr>
<td class="name" ><a href="#SetTitleScreenImagePath">SetTitleScreenImagePath(path)</a></td> <td class="name" ><a href="#SetTitleScreenImagePath">SetTitleScreenImagePath(path)</a></td>
<td class="summary">Image to show in the background of the title screen.</td> <td class="summary">Image to show in the background of the title screen.</td>
</tr> </tr>
@ -330,6 +334,29 @@ Must be a .jpg or .png image.
</dd>
<dt>
<a name = "SetIntroVideoPath"></a>
<strong>SetIntroVideoPath(path)</strong>
</dt>
<dd>
Video to show when loading the game.
Must be a common video format, such as .mp4, .mkv or .avi.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">path</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
the path to the video, relative to the TombEngine exe
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "SetTitleScreenImagePath"></a> <a name = "SetTitleScreenImagePath"></a>

View file

@ -177,7 +177,7 @@
<strong>PlayAudioTrack(filename, type)</strong> <strong>PlayAudioTrack(filename, type)</strong>
</dt> </dt>
<dd> <dd>
Play an audio track. Supported formats are wav, mp3 and ogg. Play an audio track. Should be placed in the <code>Audio</code> folder. Supported formats are wav, mp3 and ogg.

View file

@ -172,6 +172,30 @@
<td class="summary">Sets the post-process tint.</td> <td class="summary">Sets the post-process tint.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#PlayVideo">PlayVideo(fileName[, background][, silent][, loop])</a></td>
<td class="summary">Play a video file.</td>
</tr>
<tr>
<td class="name" ><a href="#StopVideo">StopVideo()</a></td>
<td class="summary">Stop the currently playing video.</td>
</tr>
<tr>
<td class="name" ><a href="#GetVideoPosition">GetVideoPosition()</a></td>
<td class="summary">Gets the currently playing video position.</td>
</tr>
<tr>
<td class="name" ><a href="#SetVideoPosition">SetVideoPosition(position)</a></td>
<td class="summary">Sets the currently playing video position.</td>
</tr>
<tr>
<td class="name" ><a href="#GetVideoDominantColor">GetVideoDominantColor()</a></td>
<td class="summary">Gets the dominant color for the current video frame.</td>
</tr>
<tr>
<td class="name" ><a href="#IsVideoPlaying">IsVideoPlaying([name])</a></td>
<td class="summary">Checks if video is currently playing.</td>
</tr>
<tr>
<td class="name" ><a href="#PlayFlyby">PlayFlyby(seqID)</a></td> <td class="name" ><a href="#PlayFlyby">PlayFlyby(seqID)</a></td>
<td class="summary">Play a flyby sequence.</td> <td class="summary">Play a flyby sequence.</td>
</tr> </tr>
@ -261,11 +285,11 @@
<ul> <ul>
<li><span class="parameter">height</span> <li><span class="parameter">height</span>
<span class="types"><span class="type">float</span></span> <span class="types"><span class="type">float</span></span>
<strong>(default 30)</strong> Percentage of the screen to be covered (default 30). Percentage of the screen to be covered
</li> </li>
<li><span class="parameter">speed</span> <li><span class="parameter">speed</span>
<span class="types"><span class="type">float</span></span> <span class="types"><span class="type">float</span></span>
<strong>(default 30)</strong> Coverage percent per second (default 30). Coverage percent per second
</li> </li>
</ul> </ul>
@ -474,6 +498,152 @@
</dd>
<dt>
<a name = "PlayVideo"></a>
<strong>PlayVideo(fileName[, background][, silent][, loop])</strong>
</dt>
<dd>
Play a video file. File should be placed in the <code>FMV</code> folder.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">fileName</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
Video file name. Can be provided without extension, if type is mp4, mkv or avi.
</li>
<li><span class="parameter">background</span>
<span class="types"><span class="type">bool</span></span>
(default: false). Play video in the background mode.
In such case, video won't play in fullscreen, but must be shown using special animated texture type in Tomb Editor, or using <a href="../2 classes/View.DisplaySprite.html#">View.DisplaySprite</a>.
(<em>optional</em>)
</li>
<li><span class="parameter">silent</span>
<span class="types"><span class="type">bool</span></span>
(default: false). Play video without sound.
(<em>optional</em>)
</li>
<li><span class="parameter">loop</span>
<span class="types"><span class="type">bool</span></span>
(default: false). Play video in a loop.
(<em>optional</em>)
</li>
</ul>
</dd>
<dt>
<a name = "StopVideo"></a>
<strong>StopVideo()</strong>
</dt>
<dd>
Stop the currently playing video. Only possible if video is playing in the background mode.
</dd>
<dt>
<a name = "GetVideoPosition"></a>
<strong>GetVideoPosition()</strong>
</dt>
<dd>
Gets the currently playing video position.
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../3 primitive classes/Time.html#">Time</a></span>
Current video position.
</ol>
</dd>
<dt>
<a name = "SetVideoPosition"></a>
<strong>SetVideoPosition(position)</strong>
</dt>
<dd>
Sets the currently playing video position.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">position</span>
<span class="types"><a class="type" href="../3 primitive classes/Time.html#">Time</a></span>
New video position.
</li>
</ul>
</dd>
<dt>
<a name = "GetVideoDominantColor"></a>
<strong>GetVideoDominantColor()</strong>
</dt>
<dd>
Gets the dominant color for the current video frame. If no video is playing, returns black.
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../3 primitive classes/Color.html#">Color</a></span>
Dominant video color.
</ol>
</dd>
<dt>
<a name = "IsVideoPlaying"></a>
<strong>IsVideoPlaying([name])</strong>
</dt>
<dd>
Checks if video is currently playing.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
Video file name. If provided, checks if the currently playing video file name is the same as the provided one.
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
True if video is currently playing.
</ol>
</dd> </dd>
<dt> <dt>
<a name = "PlayFlyby"></a> <a name = "PlayFlyby"></a>

View file

@ -128,6 +128,10 @@
<td class="summary">Create a DisplaySprite object.</td> <td class="summary">Create a DisplaySprite object.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#DisplaySprite">DisplaySprite(pos, rot, scale[, color])</a></td>
<td class="summary">Create a DisplaySprite object with a video image.</td>
</tr>
<tr>
<td class="name" ><a href="#DisplaySprite:GetObjectID">DisplaySprite:GetObjectID()</a></td> <td class="name" ><a href="#DisplaySprite:GetObjectID">DisplaySprite:GetObjectID()</a></td>
<td class="summary">Get the object ID of the sprite sequence object used by the display sprite.</td> <td class="summary">Get the object ID of the sprite sequence object used by the display sprite.</td>
</tr> </tr>
@ -193,7 +197,7 @@
<strong>DisplaySprite(ID, int, pos, rot, scale, [color])</strong> <strong>DisplaySprite(ID, int, pos, rot, scale, [color])</strong>
</dt> </dt>
<dd> <dd>
Create a DisplaySprite object. () Create a DisplaySprite object.
@ -236,6 +240,48 @@
</dd>
<dt>
<a name = "DisplaySprite"></a>
<strong>DisplaySprite(pos, rot, scale[, color])</strong>
</dt>
<dd>
Create a DisplaySprite object with a video image.
Video should be played using <a href="../1 modules/View.html#PlayVideo">View.PlayVideo</a> function in a background mode. If no video is played, sprite will not show.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">pos</span>
<span class="types"><a class="type" href="../3 primitive classes/Vec2.html#">Vec2</a></span>
Display position in percent.
</li>
<li><span class="parameter">rot</span>
<span class="types"><span class="type">float</span></span>
Rotation in degrees.
</li>
<li><span class="parameter">scale</span>
<span class="types"><a class="type" href="../3 primitive classes/Vec2.html#">Vec2</a></span>
Horizontal and vertical scale in percent. Scaling is interpreted by the DisplaySpriteEnum.ScaleMode passed to the Draw() function call.
</li>
<li><span class="parameter">color</span>
<span class="types"><a class="type" href="../3 primitive classes/Color.html#">Color</a></span>
Color. <strong>Default: Color(255, 255, 255, 255)</strong>
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../2 classes/View.DisplaySprite.html#DisplaySprite">DisplaySprite</a></span>
A new DisplaySprite object with attached video image.
</ol>
</dd> </dd>
<dt> <dt>
<a name = "DisplaySprite:GetObjectID"></a> <a name = "DisplaySprite:GetObjectID"></a>
@ -272,7 +318,7 @@
<ol> <ol>
<span class="types"><span class="type">int</span></span> <span class="types"><span class="type">int</span></span>
Sprite ID in the sprite sequence object. Sprite ID in the sprite sequence object. Value <strong>-1</strong> means that it is a background video, played using <a href="../1 modules/View.html#PlayVideo">View.PlayVideo</a>.
</ol> </ol>

546
Libs/vlc/libvlc.h Normal file
View file

@ -0,0 +1,546 @@
/*****************************************************************************
* libvlc.h: libvlc external API
*****************************************************************************
* Copyright (C) 1998-2009 VLC authors and VideoLAN
*
* Authors: Clément Stenac <zorglub@videolan.org>
* Jean-Paul Saman <jpsaman@videolan.org>
* Pierre d'Herbemont <pdherbemont@videolan.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/**
* \defgroup libvlc LibVLC
* LibVLC is the external programming interface of the VLC media player.
* It is used to embed VLC into other applications or frameworks.
* @{
* \file
* LibVLC core external API
*/
#ifndef VLC_LIBVLC_H
#define VLC_LIBVLC_H 1
#if defined (_WIN32) && defined (LIBVLC_DLL_EXPORT)
# define LIBVLC_API __declspec(dllexport)
#elif defined (__GNUC__) && (__GNUC__ >= 4)
# define LIBVLC_API __attribute__((visibility("default")))
#else
# define LIBVLC_API
#endif
#ifdef LIBVLC_INTERNAL_
/* Avoid unhelpful warnings from libvlc with our deprecated APIs */
# define LIBVLC_DEPRECATED
#elif defined(__GNUC__) && \
(__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
# define LIBVLC_DEPRECATED __attribute__((deprecated))
#else
# define LIBVLC_DEPRECATED
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
# ifdef __cplusplus
extern "C" {
# endif
/** \defgroup libvlc_core LibVLC core
* \ingroup libvlc
* Before it can do anything useful, LibVLC must be initialized.
* You can create one (or more) instance(s) of LibVLC in a given process,
* with libvlc_new() and destroy them with libvlc_release().
*
* \version Unless otherwise stated, these functions are available
* from LibVLC versions numbered 1.1.0 or more.
* Earlier versions (0.9.x and 1.0.x) are <b>not</b> compatible.
* @{
*/
/** This structure is opaque. It represents a libvlc instance */
typedef struct libvlc_instance_t libvlc_instance_t;
typedef int64_t libvlc_time_t;
/** \defgroup libvlc_error LibVLC error handling
* @{
*/
/**
* A human-readable error message for the last LibVLC error in the calling
* thread. The resulting string is valid until another error occurs (at least
* until the next LibVLC call).
*
* @warning
* This will be NULL if there was no error.
*/
LIBVLC_API const char *libvlc_errmsg (void);
/**
* Clears the LibVLC error status for the current thread. This is optional.
* By default, the error status is automatically overridden when a new error
* occurs, and destroyed when the thread exits.
*/
LIBVLC_API void libvlc_clearerr (void);
/**
* Sets the LibVLC error status and message for the current thread.
* Any previous error is overridden.
* \param fmt the format string
* \param ... the arguments for the format string
* \return a nul terminated string in any case
*/
const char *libvlc_printerr (const char *fmt, ...);
/**@} */
/**
* Create and initialize a libvlc instance.
* This functions accept a list of "command line" arguments similar to the
* main(). These arguments affect the LibVLC instance default configuration.
*
* \note
* LibVLC may create threads. Therefore, any thread-unsafe process
* initialization must be performed before calling libvlc_new(). In particular
* and where applicable:
* - setlocale() and textdomain(),
* - setenv(), unsetenv() and putenv(),
* - with the X11 display system, XInitThreads()
* (see also libvlc_media_player_set_xwindow()) and
* - on Microsoft Windows, SetErrorMode().
* - sigprocmask() shall never be invoked; pthread_sigmask() can be used.
*
* On POSIX systems, the SIGCHLD signal <b>must not</b> be ignored, i.e. the
* signal handler must set to SIG_DFL or a function pointer, not SIG_IGN.
* Also while LibVLC is active, the wait() function shall not be called, and
* any call to waitpid() shall use a strictly positive value for the first
* parameter (i.e. the PID). Failure to follow those rules may lead to a
* deadlock or a busy loop.
* Also on POSIX systems, it is recommended that the SIGPIPE signal be blocked,
* even if it is not, in principles, necessary, e.g.:
* @code
sigset_t set;
signal(SIGCHLD, SIG_DFL);
sigemptyset(&set);
sigaddset(&set, SIGPIPE);
pthread_sigmask(SIG_BLOCK, &set, NULL);
* @endcode
*
* On Microsoft Windows, setting the default DLL directories to SYSTEM32
* exclusively is strongly recommended for security reasons:
* @code
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
* @endcode
*
* \version
* Arguments are meant to be passed from the command line to LibVLC, just like
* VLC media player does. The list of valid arguments depends on the LibVLC
* version, the operating system and platform, and set of available LibVLC
* plugins. Invalid or unsupported arguments will cause the function to fail
* (i.e. return NULL). Also, some arguments may alter the behaviour or
* otherwise interfere with other LibVLC functions.
*
* \warning
* There is absolutely no warranty or promise of forward, backward and
* cross-platform compatibility with regards to libvlc_new() arguments.
* We recommend that you do not use them, other than when debugging.
*
* \param argc the number of arguments (should be 0)
* \param argv list of arguments (should be NULL)
* \return the libvlc instance or NULL in case of error
*/
LIBVLC_API libvlc_instance_t *
libvlc_new( int argc , const char *const *argv );
/**
* Decrement the reference count of a libvlc instance, and destroy it
* if it reaches zero.
*
* \param p_instance the instance to destroy
*/
LIBVLC_API void libvlc_release( libvlc_instance_t *p_instance );
/**
* Increments the reference count of a libvlc instance.
* The initial reference count is 1 after libvlc_new() returns.
*
* \param p_instance the instance to reference
* \return the same object
*/
LIBVLC_API libvlc_instance_t *libvlc_retain( libvlc_instance_t *p_instance );
/**
* Get the ABI version of the libvlc library.
*
* This is different than the VLC version, which is the version of the whole
* VLC package. The value is the same as LIBVLC_ABI_VERSION_INT used when
* compiling.
*
* \return a value with the following mask in hexadecimal
* 0xFF000000: major VLC version, similar to VLC major version,
* 0x00FF0000: major ABI version, incremented incompatible changes are added,
* 0x0000FF00: minor ABI version, incremented when new functions are added
* 0x000000FF: micro ABI version, incremented with new release/builds
*
* \note This the same value as the .so version but cross platform.
*/
LIBVLC_API int libvlc_abi_version(void);
/**
* Sets the application name. LibVLC passes this as the user agent string
* when a protocol requires it.
*
* \param p_instance LibVLC instance
* \param name human-readable application name, e.g. "FooBar player 1.2.3"
* \param http HTTP User Agent, e.g. "FooBar/1.2.3 Python/2.6.0"
* \version LibVLC 1.1.1 or later
*/
LIBVLC_API
void libvlc_set_user_agent( libvlc_instance_t *p_instance,
const char *name, const char *http );
/**
* Sets some meta-information about the application.
* See also libvlc_set_user_agent().
*
* \param p_instance LibVLC instance
* \param id Java-style application identifier, e.g. "com.acme.foobar"
* \param version application version numbers, e.g. "1.2.3"
* \param icon application icon name, e.g. "foobar"
* \version LibVLC 2.1.0 or later.
*/
LIBVLC_API
void libvlc_set_app_id( libvlc_instance_t *p_instance, const char *id,
const char *version, const char *icon );
/**
* Retrieve libvlc version.
*
* Example: "1.1.0-git The Luggage"
*
* \return a string containing the libvlc version
*/
LIBVLC_API const char * libvlc_get_version(void);
/**
* Retrieve libvlc compiler version.
*
* Example: "gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu6)"
*
* \return a string containing the libvlc compiler version
*/
LIBVLC_API const char * libvlc_get_compiler(void);
/**
* Retrieve libvlc changeset.
*
* Example: "aa9bce0bc4"
*
* \return a string containing the libvlc changeset
*/
LIBVLC_API const char * libvlc_get_changeset(void);
/**
* Frees an heap allocation returned by a LibVLC function.
* If you know you're using the same underlying C run-time as the LibVLC
* implementation, then you can call ANSI C free() directly instead.
*
* \param ptr the pointer
*/
LIBVLC_API void libvlc_free( void *ptr );
/** \defgroup libvlc_event LibVLC asynchronous events
* LibVLC emits asynchronous events.
*
* Several LibVLC objects (such @ref libvlc_instance_t as
* @ref libvlc_media_player_t) generate events asynchronously. Each of them
* provides @ref libvlc_event_manager_t event manager. You can subscribe to
* events with libvlc_event_attach() and unsubscribe with
* libvlc_event_detach().
* @{
*/
/**
* Event manager that belongs to a libvlc object, and from whom events can
* be received.
*/
typedef struct libvlc_event_manager_t libvlc_event_manager_t;
struct libvlc_event_t;
/**
* Type of a LibVLC event.
*/
typedef int libvlc_event_type_t;
/**
* Callback function notification
* \param p_event the event triggering the callback
*/
typedef void ( *libvlc_callback_t )( const struct libvlc_event_t *p_event, void *p_data );
/**
* Register for an event notification.
*
* \param p_event_manager the event manager to which you want to attach to.
* Generally it is obtained by vlc_my_object_event_manager() where
* my_object is the object you want to listen to.
* \param i_event_type the desired event to which we want to listen
* \param f_callback the function to call when i_event_type occurs
* \param user_data user provided data to carry with the event
* \return 0 on success, ENOMEM on error
*/
LIBVLC_API int libvlc_event_attach( libvlc_event_manager_t *p_event_manager,
libvlc_event_type_t i_event_type,
libvlc_callback_t f_callback,
void *user_data );
/**
* Unregister an event notification.
*
* \param p_event_manager the event manager
* \param i_event_type the desired event to which we want to unregister
* \param f_callback the function to call when i_event_type occurs
* \param p_user_data user provided data to carry with the event
*/
LIBVLC_API void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
libvlc_event_type_t i_event_type,
libvlc_callback_t f_callback,
void *p_user_data );
/** @} */
/** \defgroup libvlc_log LibVLC logging
* libvlc_log_* functions provide access to the LibVLC messages log.
* This is used for logging and debugging.
* @{
*/
/**
* Logging messages level.
* \note Future LibVLC versions may define new levels.
*/
enum libvlc_log_level
{
LIBVLC_DEBUG=0, /**< Debug message */
LIBVLC_NOTICE=2, /**< Important informational message */
LIBVLC_WARNING=3, /**< Warning (potential error) message */
LIBVLC_ERROR=4 /**< Error message */
};
typedef struct vlc_log_t libvlc_log_t;
/**
* Gets log message debug infos.
*
* This function retrieves self-debug information about a log message:
* - the name of the VLC module emitting the message,
* - the name of the source code module (i.e. file) and
* - the line number within the source code module.
*
* The returned module name and file name will be NULL if unknown.
* The returned line number will similarly be zero if unknown.
*
* \param ctx message context (as passed to the @ref libvlc_log_cb callback)
* \param module module name storage (or NULL) [OUT]
* \param file source code file name storage (or NULL) [OUT]
* \param line source code file line number storage (or NULL) [OUT]
* \warning The returned module name and source code file name, if non-NULL,
* are only valid until the logging callback returns.
*
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API void libvlc_log_get_context(const libvlc_log_t *ctx,
const char **module, const char **file, unsigned *line);
/**
* Gets log message info.
*
* This function retrieves meta-information about a log message:
* - the type name of the VLC object emitting the message,
* - the object header if any, and
* - a temporaly-unique object identifier.
*
* This information is mainly meant for <b>manual</b> troubleshooting.
*
* The returned type name may be "generic" if unknown, but it cannot be NULL.
* The returned header will be NULL if unset; in current versions, the header
* is used to distinguish for VLM inputs.
* The returned object ID will be zero if the message is not associated with
* any VLC object.
*
* \param ctx message context (as passed to the @ref libvlc_log_cb callback)
* \param name object name storage (or NULL) [OUT]
* \param header object header (or NULL) [OUT]
* \param id temporarily-unique object identifier (or 0) [OUT]
* \warning The returned module name and source code file name, if non-NULL,
* are only valid until the logging callback returns.
*
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API void libvlc_log_get_object(const libvlc_log_t *ctx,
const char **name, const char **header, uintptr_t *id);
/**
* Callback prototype for LibVLC log message handler.
*
* \param data data pointer as given to libvlc_log_set()
* \param level message level (@ref libvlc_log_level)
* \param ctx message context (meta-information about the message)
* \param fmt printf() format string (as defined by ISO C11)
* \param args variable argument list for the format
* \note Log message handlers <b>must</b> be thread-safe.
* \warning The message context pointer, the format string parameters and the
* variable arguments are only valid until the callback returns.
*/
typedef void (*libvlc_log_cb)(void *data, int level, const libvlc_log_t *ctx,
const char *fmt, va_list args);
/**
* Unsets the logging callback.
*
* This function deregisters the logging callback for a LibVLC instance.
* This is rarely needed as the callback is implicitly unset when the instance
* is destroyed.
*
* \note This function will wait for any pending callbacks invocation to
* complete (causing a deadlock if called from within the callback).
*
* \param p_instance libvlc instance
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API void libvlc_log_unset( libvlc_instance_t *p_instance );
/**
* Sets the logging callback for a LibVLC instance.
*
* This function is thread-safe: it will wait for any pending callbacks
* invocation to complete.
*
* \param cb callback function pointer
* \param data opaque data pointer for the callback function
*
* \note Some log messages (especially debug) are emitted by LibVLC while
* is being initialized. These messages cannot be captured with this interface.
*
* \warning A deadlock may occur if this function is called from the callback.
*
* \param p_instance libvlc instance
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API void libvlc_log_set( libvlc_instance_t *p_instance,
libvlc_log_cb cb, void *data );
/**
* Sets up logging to a file.
* \param p_instance libvlc instance
* \param stream FILE pointer opened for writing
* (the FILE pointer must remain valid until libvlc_log_unset())
* \version LibVLC 2.1.0 or later
*/
LIBVLC_API void libvlc_log_set_file( libvlc_instance_t *p_instance, FILE *stream );
/** @} */
/**
* Description of a module.
*/
typedef struct libvlc_module_description_t
{
char *psz_name;
char *psz_shortname;
char *psz_longname;
char *psz_help;
char *psz_help_html;
struct libvlc_module_description_t *p_next;
} libvlc_module_description_t;
/**
* Release a list of module descriptions.
*
* \param p_list the list to be released
*/
LIBVLC_API
void libvlc_module_description_list_release( libvlc_module_description_t *p_list );
/**
* Returns a list of audio filters that are available.
*
* \param p_instance libvlc instance
*
* \return a list of module descriptions. It should be freed with libvlc_module_description_list_release().
* In case of an error, NULL is returned.
*
* \see libvlc_module_description_t
* \see libvlc_module_description_list_release
*/
LIBVLC_API
libvlc_module_description_t *libvlc_audio_filter_list_get( libvlc_instance_t *p_instance );
/**
* Returns a list of video filters that are available.
*
* \param p_instance libvlc instance
*
* \return a list of module descriptions. It should be freed with libvlc_module_description_list_release().
* In case of an error, NULL is returned.
*
* \see libvlc_module_description_t
* \see libvlc_module_description_list_release
*/
LIBVLC_API
libvlc_module_description_t *libvlc_video_filter_list_get( libvlc_instance_t *p_instance );
/** @} */
/** \defgroup libvlc_clock LibVLC time
* These functions provide access to the LibVLC time/clock.
* @{
*/
/**
* Return the current time as defined by LibVLC. The unit is the microsecond.
* Time increases monotonically (regardless of time zone changes and RTC
* adjustments).
* The origin is arbitrary but consistent across the whole system
* (e.g. the system uptime, the time since the system was booted).
* \note On systems that support it, the POSIX monotonic clock is used.
*/
LIBVLC_API
int64_t libvlc_clock(void);
/**
* Return the delay (in microseconds) until a certain timestamp.
* \param pts timestamp
* \return negative if timestamp is in the past,
* positive if it is in the future
*/
static inline int64_t libvlc_delay(int64_t pts)
{
return pts - libvlc_clock();
}
/** @} */
# ifdef __cplusplus
}
# endif
#endif /** @} */

260
Libs/vlc/libvlc_dialog.h Normal file
View file

@ -0,0 +1,260 @@
/*****************************************************************************
* libvlc_dialog.h: libvlc dialog API
*****************************************************************************
* Copyright © 2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef LIBVLC_DIALOG_H
#define LIBVLC_DIALOG_H 1
#include <stdbool.h>
# ifdef __cplusplus
extern "C" {
# endif
typedef struct libvlc_dialog_id libvlc_dialog_id;
/**
* @defgroup libvlc_dialog LibVLC dialog
* @ingroup libvlc
* @{
* @file
* LibVLC dialog external API
*/
typedef enum libvlc_dialog_question_type
{
LIBVLC_DIALOG_QUESTION_NORMAL,
LIBVLC_DIALOG_QUESTION_WARNING,
LIBVLC_DIALOG_QUESTION_CRITICAL,
} libvlc_dialog_question_type;
/**
* Dialog callbacks to be implemented
*
* @attention starting with vlc 4.0.0 the error callback (pf_display_error) is
* no longer part of this struct and need to be registered separately
* using @a libvlc_dialog_set_error_callback
*
* @see libvlc_dialog_set_error_callback
*/
typedef struct libvlc_dialog_cbs
{
/**
* Called when a login dialog needs to be displayed
*
* You can interact with this dialog by calling libvlc_dialog_post_login()
* to post an answer or libvlc_dialog_dismiss() to cancel this dialog.
*
* @note to receive this callback, libvlc_dialog_cbs.pf_cancel should not be
* NULL.
*
* @param p_data opaque pointer for the callback
* @param p_id id used to interact with the dialog
* @param psz_title title of the dialog
* @param psz_text text of the dialog
* @param psz_default_username user name that should be set on the user form
* @param b_ask_store if true, ask the user if he wants to save the
* credentials
*/
void (*pf_display_login)(void *p_data, libvlc_dialog_id *p_id,
const char *psz_title, const char *psz_text,
const char *psz_default_username,
bool b_ask_store);
/**
* Called when a question dialog needs to be displayed
*
* You can interact with this dialog by calling libvlc_dialog_post_action()
* to post an answer or libvlc_dialog_dismiss() to cancel this dialog.
*
* @note to receive this callback, libvlc_dialog_cbs.pf_cancel should not be
* NULL.
*
* @param p_data opaque pointer for the callback
* @param p_id id used to interact with the dialog
* @param psz_title title of the dialog
* @param psz_text text of the dialog
* @param i_type question type (or severity) of the dialog
* @param psz_cancel text of the cancel button
* @param psz_action1 text of the first button, if NULL, don't display this
* button
* @param psz_action2 text of the second button, if NULL, don't display
* this button
*/
void (*pf_display_question)(void *p_data, libvlc_dialog_id *p_id,
const char *psz_title, const char *psz_text,
libvlc_dialog_question_type i_type,
const char *psz_cancel, const char *psz_action1,
const char *psz_action2);
/**
* Called when a progress dialog needs to be displayed
*
* If cancellable (psz_cancel != NULL), you can cancel this dialog by
* calling libvlc_dialog_dismiss()
*
* @note to receive this callback, libvlc_dialog_cbs.pf_cancel and
* libvlc_dialog_cbs.pf_update_progress should not be NULL.
*
* @param p_data opaque pointer for the callback
* @param p_id id used to interact with the dialog
* @param psz_title title of the dialog
* @param psz_text text of the dialog
* @param b_indeterminate true if the progress dialog is indeterminate
* @param f_position initial position of the progress bar (between 0.0 and
* 1.0)
* @param psz_cancel text of the cancel button, if NULL the dialog is not
* cancellable
*/
void (*pf_display_progress)(void *p_data, libvlc_dialog_id *p_id,
const char *psz_title, const char *psz_text,
bool b_indeterminate, float f_position,
const char *psz_cancel);
/**
* Called when a displayed dialog needs to be cancelled
*
* The implementation must call libvlc_dialog_dismiss() to really release
* the dialog.
*
* @param p_data opaque pointer for the callback
* @param p_id id of the dialog
*/
void (*pf_cancel)(void *p_data, libvlc_dialog_id *p_id);
/**
* Called when a progress dialog needs to be updated
*
* @param p_data opaque pointer for the callback
* @param p_id id of the dialog
* @param f_position osition of the progress bar (between 0.0 and 1.0)
* @param psz_text new text of the progress dialog
*/
void (*pf_update_progress)(void *p_data, libvlc_dialog_id *p_id,
float f_position, const char *psz_text);
} libvlc_dialog_cbs;
/**
* Called when an error message needs to be displayed
*
* @param p_data opaque pointer for the callback
* @param psz_title title of the dialog
* @param psz_text text of the dialog
*/
typedef void (*libvlc_dialog_error_cbs)(void *p_data, const char *psz_title, const char *psz_text);
/**
* Register callbacks in order to handle VLC dialogs
*
* @version LibVLC 3.0.0 and later.
*
* @param p_instance the libvlc instance to attach the dialog callbacks to
* @param p_cbs a pointer to callbacks, or NULL to unregister callbacks.
* @param p_data opaque pointer for the callback
*/
LIBVLC_API void
libvlc_dialog_set_callbacks(libvlc_instance_t *p_instance,
const libvlc_dialog_cbs *p_cbs, void *p_data);
/*
* Register callback in order to handle VLC error messages
*
* @version LibVLC 4.0.0 and later.
*
* @param p_cbs a pointer to callback, or NULL to unregister callback.
* @param p_data opaque pointer for the callback
*/
LIBVLC_API void
libvlc_dialog_set_error_callback(libvlc_instance_t *p_instance,
libvlc_dialog_error_cbs p_cbs, void *p_data);
/**
* Associate an opaque pointer with the dialog id
*
* @version LibVLC 3.0.0 and later.
*/
LIBVLC_API void
libvlc_dialog_set_context(libvlc_dialog_id *p_id, void *p_context);
/**
* Return the opaque pointer associated with the dialog id
* \see libvlc_dialog_set_context
* @version LibVLC 3.0.0 and later.
*/
LIBVLC_API void *
libvlc_dialog_get_context(libvlc_dialog_id *p_id);
/**
* Post a login answer
*
* After this call, p_id won't be valid anymore
*
* @see libvlc_dialog_cbs.pf_display_login
*
* @version LibVLC 3.0.0 and later.
*
* @param p_id id of the dialog
* @param psz_username valid and non empty string
* @param psz_password valid string (can be empty)
* @param b_store if true, store the credentials
* @return 0 on success, or -1 on error
*/
LIBVLC_API int
libvlc_dialog_post_login(libvlc_dialog_id *p_id, const char *psz_username,
const char *psz_password, bool b_store);
/**
* Post a question answer
*
* After this call, p_id won't be valid anymore
*
* @see libvlc_dialog_cbs.pf_display_question
*
* @version LibVLC 3.0.0 and later.
*
* @param p_id id of the dialog
* @param i_action 1 for action1, 2 for action2
* @return 0 on success, or -1 on error
*/
LIBVLC_API int
libvlc_dialog_post_action(libvlc_dialog_id *p_id, int i_action);
/**
* Dismiss a dialog
*
* After this call, p_id won't be valid anymore
*
* @see libvlc_dialog_cbs.pf_cancel
*
* @version LibVLC 3.0.0 and later.
*
* @param p_id id of the dialog
* @return 0 on success, or -1 on error
*/
LIBVLC_API int
libvlc_dialog_dismiss(libvlc_dialog_id *p_id);
/** @} */
# ifdef __cplusplus
}
# endif
#endif /* LIBVLC_DIALOG_H */

457
Libs/vlc/libvlc_events.h Normal file
View file

@ -0,0 +1,457 @@
/*****************************************************************************
* libvlc_events.h: libvlc_events external API structure
*****************************************************************************
* Copyright (C) 1998-2010 VLC authors and VideoLAN
*
* Authors: Filippo Carone <littlejohn@videolan.org>
* Pierre d'Herbemont <pdherbemont@videolan.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef LIBVLC_EVENTS_H
#define LIBVLC_EVENTS_H 1
# include <vlc/libvlc.h>
# include <vlc/libvlc_picture.h>
# include <vlc/libvlc_media_track.h>
# include <vlc/libvlc_media.h>
/**
* \file
* This file defines libvlc_event external API
*/
# ifdef __cplusplus
extern "C" {
# else
# include <stdbool.h>
# endif
typedef struct libvlc_renderer_item_t libvlc_renderer_item_t;
typedef struct libvlc_title_description_t libvlc_title_description_t;
typedef struct libvlc_picture_t libvlc_picture_t;
typedef struct libvlc_picture_list_t libvlc_picture_list_t;
typedef struct libvlc_media_t libvlc_media_t;
typedef struct libvlc_media_list_t libvlc_media_list_t;
/**
* \ingroup libvlc_event
* @{
*/
/**
* Event types
*/
enum libvlc_event_e {
/* Append new event types at the end of a category.
* Do not remove, insert or re-order any entry.
*/
/**
* 1 or several Metadata of a \link #libvlc_media_t media item\endlink changed
*/
libvlc_MediaMetaChanged=0,
/**
* Subitem was added to a \link #libvlc_media_t media item\endlink
* \see libvlc_media_subitems()
*/
libvlc_MediaSubItemAdded,
/**
* Deprecated, use libvlc_MediaParsedChanged or libvlc_MediaPlayerLengthChanged.
*/
libvlc_MediaDurationChanged,
/**
* Parsing state of a \link #libvlc_media_t media item\endlink changed
* \see libvlc_media_parse_request(),
* libvlc_media_get_parsed_status(),
* libvlc_media_parse_stop()
*/
libvlc_MediaParsedChanged,
/* Removed: libvlc_MediaFreed, */
/* Removed: libvlc_MediaStateChanged */
/**
* Subitem tree was added to a \link #libvlc_media_t media item\endlink
*/
libvlc_MediaSubItemTreeAdded = libvlc_MediaParsedChanged + 3,
/**
* A thumbnail generation for this \link #libvlc_media_t media \endlink completed.
* \see libvlc_media_thumbnail_request_by_time()
* \see libvlc_media_thumbnail_request_by_pos()
*/
libvlc_MediaThumbnailGenerated,
/**
* One or more embedded thumbnails were found during the media preparsing
* The user can hold these picture(s) using libvlc_picture_retain if they
* wish to use them
*/
libvlc_MediaAttachedThumbnailsFound,
libvlc_MediaPlayerMediaChanged=0x100,
libvlc_MediaPlayerNothingSpecial,
libvlc_MediaPlayerOpening,
libvlc_MediaPlayerBuffering,
libvlc_MediaPlayerPlaying,
libvlc_MediaPlayerPaused,
libvlc_MediaPlayerStopped,
libvlc_MediaPlayerForward,
libvlc_MediaPlayerBackward,
libvlc_MediaPlayerStopping,
libvlc_MediaPlayerEncounteredError,
libvlc_MediaPlayerTimeChanged,
libvlc_MediaPlayerPositionChanged,
libvlc_MediaPlayerSeekableChanged,
libvlc_MediaPlayerPausableChanged,
/* libvlc_MediaPlayerTitleChanged, */
libvlc_MediaPlayerSnapshotTaken = libvlc_MediaPlayerPausableChanged + 2,
libvlc_MediaPlayerLengthChanged,
libvlc_MediaPlayerVout,
/* libvlc_MediaPlayerScrambledChanged, use libvlc_MediaPlayerProgramUpdated */
/** A track was added, cf. media_player_es_changed in \ref libvlc_event_t.u
* to get the id of the new track. */
libvlc_MediaPlayerESAdded = libvlc_MediaPlayerVout + 2,
/** A track was removed, cf. media_player_es_changed in \ref
* libvlc_event_t.u to get the id of the removed track. */
libvlc_MediaPlayerESDeleted,
/** Tracks were selected or unselected, cf.
* media_player_es_selection_changed in \ref libvlc_event_t.u to get the
* unselected and/or the selected track ids. */
libvlc_MediaPlayerESSelected,
libvlc_MediaPlayerCorked,
libvlc_MediaPlayerUncorked,
libvlc_MediaPlayerMuted,
libvlc_MediaPlayerUnmuted,
libvlc_MediaPlayerAudioVolume,
libvlc_MediaPlayerAudioDevice,
/** A track was updated, cf. media_player_es_changed in \ref
* libvlc_event_t.u to get the id of the updated track. */
libvlc_MediaPlayerESUpdated,
libvlc_MediaPlayerProgramAdded,
libvlc_MediaPlayerProgramDeleted,
libvlc_MediaPlayerProgramSelected,
libvlc_MediaPlayerProgramUpdated,
/**
* The title list changed, call
* libvlc_media_player_get_full_title_descriptions() to get the new list.
*/
libvlc_MediaPlayerTitleListChanged,
/**
* The title selection changed, cf media_player_title_selection_changed in
* \ref libvlc_event_t.u
*/
libvlc_MediaPlayerTitleSelectionChanged,
libvlc_MediaPlayerChapterChanged,
libvlc_MediaPlayerRecordChanged,
/**
* A \link #libvlc_media_t media item\endlink was added to a
* \link #libvlc_media_list_t media list\endlink.
*/
libvlc_MediaListItemAdded=0x200,
/**
* A \link #libvlc_media_t media item\endlink is about to get
* added to a \link #libvlc_media_list_t media list\endlink.
*/
libvlc_MediaListWillAddItem,
/**
* A \link #libvlc_media_t media item\endlink was deleted from
* a \link #libvlc_media_list_t media list\endlink.
*/
libvlc_MediaListItemDeleted,
/**
* A \link #libvlc_media_t media item\endlink is about to get
* deleted from a \link #libvlc_media_list_t media list\endlink.
*/
libvlc_MediaListWillDeleteItem,
/**
* A \link #libvlc_media_list_t media list\endlink has reached the
* end.
* All \link #libvlc_media_t items\endlink were either added (in
* case of a \ref libvlc_media_discoverer_t) or parsed (preparser).
*/
libvlc_MediaListEndReached,
/**
* \deprecated No longer used.
* This belonged to the removed libvlc_media_list_view_t
*/
libvlc_MediaListViewItemAdded LIBVLC_DEPRECATED =0x300,
/**
* \deprecated No longer used.
* This belonged to the removed libvlc_media_list_view_t
*/
libvlc_MediaListViewWillAddItem LIBVLC_DEPRECATED,
/**
* \deprecated No longer used.
* This belonged to the removed libvlc_media_list_view_t
*/
libvlc_MediaListViewItemDeleted LIBVLC_DEPRECATED,
/**
* \deprecated No longer used.
* This belonged to the removed libvlc_media_list_view_t
*/
libvlc_MediaListViewWillDeleteItem LIBVLC_DEPRECATED,
/**
* Playback of a \link #libvlc_media_list_player_t media list
* player\endlink has started.
*/
libvlc_MediaListPlayerPlayed=0x400,
/**
* The current \link #libvlc_media_t item\endlink of a
* \link #libvlc_media_list_player_t media list player\endlink
* has changed to a different item.
*/
libvlc_MediaListPlayerNextItemSet,
/**
* Playback of a \link #libvlc_media_list_player_t media list
* player\endlink has stopped.
*/
libvlc_MediaListPlayerStopped,
/**
* A new \link #libvlc_renderer_item_t renderer item\endlink was found by a
* \link #libvlc_renderer_discoverer_t renderer discoverer\endlink.
* The renderer item is valid until deleted.
*/
libvlc_RendererDiscovererItemAdded=0x502,
/**
* A previously discovered \link #libvlc_renderer_item_t renderer item\endlink
* was deleted by a \link #libvlc_renderer_discoverer_t renderer discoverer\endlink.
* The renderer item is no longer valid.
*/
libvlc_RendererDiscovererItemDeleted,
/**
* The current media set into the \ref libvlc_media_player_t is stopping.
*
* This event can be used to notify when the media callbacks, initialized
* from \ref libvlc_media_new_callbacks, should be interrupted, and in
* particular the \ref libvlc_media_read_cb. It can also be used to signal
* the application state that any input resource (webserver, file mounting,
* etc) can be discarded. Output resources still need to be active until
* the player switches to the \ref libvlc_Stopped state.
*/
libvlc_MediaPlayerMediaStopping,
};
/**
* A LibVLC event
*/
typedef struct libvlc_event_t
{
int type; /**< Event type (see @ref libvlc_event_e) */
void *p_obj; /**< Object emitting the event */
union
{
/* media descriptor */
struct
{
libvlc_meta_t meta_type; /**< Deprecated, any meta_type can change */
} media_meta_changed;
struct
{
libvlc_media_t * new_child;
} media_subitem_added;
struct
{
int64_t new_duration;
} media_duration_changed;
struct
{
int new_status; /**< see @ref libvlc_media_parsed_status_t */
} media_parsed_changed;
struct
{
int new_state; /**< see @ref libvlc_state_t */
} media_state_changed;
struct
{
libvlc_picture_t* p_thumbnail;
} media_thumbnail_generated;
struct
{
libvlc_media_t * item;
} media_subitemtree_added;
struct
{
libvlc_picture_list_t* thumbnails;
} media_attached_thumbnails_found;
/* media instance */
struct
{
float new_cache;
} media_player_buffering;
struct
{
int new_chapter;
} media_player_chapter_changed;
struct
{
double new_position;
} media_player_position_changed;
struct
{
libvlc_time_t new_time;
} media_player_time_changed;
struct
{
const libvlc_title_description_t *title;
int index;
} media_player_title_selection_changed;
struct
{
int new_seekable;
} media_player_seekable_changed;
struct
{
int new_pausable;
} media_player_pausable_changed;
struct
{
int new_scrambled;
} media_player_scrambled_changed;
struct
{
int new_count;
} media_player_vout;
/* media list */
struct
{
libvlc_media_t * item;
int index;
} media_list_item_added;
struct
{
libvlc_media_t * item;
int index;
} media_list_will_add_item;
struct
{
libvlc_media_t * item;
int index;
} media_list_item_deleted;
struct
{
libvlc_media_t * item;
int index;
} media_list_will_delete_item;
/* media list player */
struct
{
libvlc_media_t * item;
} media_list_player_next_item_set;
/* snapshot taken */
struct
{
char* psz_filename ;
} media_player_snapshot_taken ;
/* Length changed */
struct
{
libvlc_time_t new_length;
} media_player_length_changed;
/* Extra MediaPlayer */
struct
{
libvlc_media_t * new_media;
} media_player_media_changed;
struct
{
libvlc_media_t * media;
} media_player_media_stopping;
/* ESAdded, ESDeleted, ESUpdated */
struct
{
libvlc_track_type_t i_type;
int i_id; /**< Deprecated, use psz_id */
/** Call libvlc_media_player_get_track_from_id() to get the track
* description. */
const char *psz_id;
} media_player_es_changed;
/* ESSelected */
struct
{
libvlc_track_type_t i_type;
const char *psz_unselected_id;
const char *psz_selected_id;
} media_player_es_selection_changed;
/* ProgramAdded, ProgramDeleted, ProgramUpdated */
struct
{
int i_id;
} media_player_program_changed;
/* ProgramSelected */
struct
{
int i_unselected_id;
int i_selected_id;
} media_player_program_selection_changed;
struct
{
float volume;
} media_player_audio_volume;
struct
{
const char *device;
} media_player_audio_device;
struct
{
bool recording;
/** Only valid when recording ends (recording == false) */
const char *recorded_file_path;
} media_player_record_changed;
struct
{
libvlc_renderer_item_t *item;
} renderer_discoverer_item_added;
struct
{
libvlc_renderer_item_t *item;
} renderer_discoverer_item_deleted;
} u; /**< Type-dependent event description */
} libvlc_event_t;
/**@} */
# ifdef __cplusplus
}
# endif
#endif /* _LIBVLC_EVENTS_H */

917
Libs/vlc/libvlc_media.h Normal file
View file

@ -0,0 +1,917 @@
/*****************************************************************************
* libvlc_media.h: libvlc external API
*****************************************************************************
* Copyright (C) 1998-2009 VLC authors and VideoLAN
*
* Authors: Clément Stenac <zorglub@videolan.org>
* Jean-Paul Saman <jpsaman@videolan.org>
* Pierre d'Herbemont <pdherbemont@videolan.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_LIBVLC_MEDIA_H
#define VLC_LIBVLC_MEDIA_H 1
#include <vlc/libvlc_picture.h>
#include <vlc/libvlc_media_track.h>
# ifdef __cplusplus
extern "C" {
# else
# include <stdbool.h>
# endif
#include <stddef.h>
/** \defgroup libvlc_media LibVLC media
* \ingroup libvlc
* @ref libvlc_media_t is an abstract representation of a playable media.
* It consists of a media location and various optional meta data.
* @{
* \file
* LibVLC media item/descriptor external API
*/
typedef struct libvlc_media_t libvlc_media_t;
/** Meta data types */
typedef enum libvlc_meta_t {
libvlc_meta_Title,
libvlc_meta_Artist,
libvlc_meta_Genre,
libvlc_meta_Copyright,
libvlc_meta_Album,
libvlc_meta_TrackNumber,
libvlc_meta_Description,
libvlc_meta_Rating,
libvlc_meta_Date,
libvlc_meta_Setting,
libvlc_meta_URL,
libvlc_meta_Language,
libvlc_meta_NowPlaying,
libvlc_meta_Publisher,
libvlc_meta_EncodedBy,
libvlc_meta_ArtworkURL,
libvlc_meta_TrackID,
libvlc_meta_TrackTotal,
libvlc_meta_Director,
libvlc_meta_Season,
libvlc_meta_Episode,
libvlc_meta_ShowName,
libvlc_meta_Actors,
libvlc_meta_AlbumArtist,
libvlc_meta_DiscNumber,
libvlc_meta_DiscTotal
/* Add new meta types HERE */
} libvlc_meta_t;
/**
* libvlc media or media_player state
*/
typedef enum libvlc_state_t
{
libvlc_NothingSpecial=0,
libvlc_Opening,
libvlc_Buffering, /* XXX: Deprecated value. Check the
* libvlc_MediaPlayerBuffering event to know the
* buffering state of a libvlc_media_player */
libvlc_Playing,
libvlc_Paused,
libvlc_Stopped,
libvlc_Stopping,
libvlc_Error
} libvlc_state_t;
enum
{
libvlc_media_option_trusted = 0x2,
libvlc_media_option_unique = 0x100
};
typedef struct libvlc_media_stats_t
{
/* Input */
uint64_t i_read_bytes;
float f_input_bitrate;
/* Demux */
uint64_t i_demux_read_bytes;
float f_demux_bitrate;
uint64_t i_demux_corrupted;
uint64_t i_demux_discontinuity;
/* Decoders */
uint64_t i_decoded_video;
uint64_t i_decoded_audio;
/* Video Output */
uint64_t i_displayed_pictures;
uint64_t i_late_pictures;
uint64_t i_lost_pictures;
/* Audio output */
uint64_t i_played_abuffers;
uint64_t i_lost_abuffers;
} libvlc_media_stats_t;
/**
* Media type
*
* \see libvlc_media_get_type
*/
typedef enum libvlc_media_type_t {
libvlc_media_type_unknown,
libvlc_media_type_file,
libvlc_media_type_directory,
libvlc_media_type_disc,
libvlc_media_type_stream,
libvlc_media_type_playlist,
} libvlc_media_type_t;
/**
* Parse flags used by libvlc_media_parse_request()
*/
typedef enum libvlc_media_parse_flag_t
{
/**
* Parse media if it's a local file
*/
libvlc_media_parse_local = 0x01,
/**
* Parse media even if it's a network file
*/
libvlc_media_parse_network = 0x02,
/**
* Force parsing the media even if it would be skipped.
*/
libvlc_media_parse_forced = 0x04,
/**
* Fetch meta and cover art using local resources
*/
libvlc_media_fetch_local = 0x08,
/**
* Fetch meta and cover art using network resources
*/
libvlc_media_fetch_network = 0x10,
/**
* Interact with the user (via libvlc_dialog_cbs) when preparsing this item
* (and not its sub items). Set this flag in order to receive a callback
* when the input is asking for credentials.
*/
libvlc_media_do_interact = 0x20,
} libvlc_media_parse_flag_t;
/**
* Parse status used sent by libvlc_media_parse_request() or returned by
* libvlc_media_get_parsed_status()
*/
typedef enum libvlc_media_parsed_status_t
{
libvlc_media_parsed_status_none,
libvlc_media_parsed_status_pending,
libvlc_media_parsed_status_skipped,
libvlc_media_parsed_status_failed,
libvlc_media_parsed_status_timeout,
libvlc_media_parsed_status_cancelled,
libvlc_media_parsed_status_done,
} libvlc_media_parsed_status_t;
/**
* Type of a media slave: subtitle or audio.
*/
typedef enum libvlc_media_slave_type_t
{
libvlc_media_slave_type_subtitle,
libvlc_media_slave_type_generic,
libvlc_media_slave_type_audio = libvlc_media_slave_type_generic,
} libvlc_media_slave_type_t;
/**
* A slave of a libvlc_media_t
* \see libvlc_media_slaves_get
*/
typedef struct libvlc_media_slave_t
{
char * psz_uri;
libvlc_media_slave_type_t i_type;
unsigned int i_priority;
} libvlc_media_slave_t;
/**
* Type of stat that can be requested from libvlc_media_get_filestat()
*/
#define libvlc_media_filestat_mtime 0
#define libvlc_media_filestat_size 1
/**
* Callback prototype to open a custom bitstream input media.
*
* The same media item can be opened multiple times. Each time, this callback
* is invoked. It should allocate and initialize any instance-specific
* resources, then store them in *datap. The instance resources can be freed
* in the @ref libvlc_media_close_cb callback.
*
* \param opaque private pointer as passed to libvlc_media_new_callbacks()
* \param datap storage space for a private data pointer [OUT]
* \param sizep byte length of the bitstream or UINT64_MAX if unknown [OUT]
*
* \note For convenience, *datap is initially NULL and *sizep is initially 0.
*
* \return 0 on success, non-zero on error. In case of failure, the other
* callbacks will not be invoked and any value stored in *datap and *sizep is
* discarded.
*/
typedef int (*libvlc_media_open_cb)(void *opaque, void **datap,
uint64_t *sizep);
/**
* Callback prototype to read data from a custom bitstream input media.
*
* \param opaque private pointer as set by the @ref libvlc_media_open_cb
* callback
* \param buf start address of the buffer to read data into
* \param len bytes length of the buffer
*
* \return strictly positive number of bytes read, 0 on end-of-stream,
* or -1 on non-recoverable error
*
* \note If no data is immediately available, then the callback should sleep.
* \warning The application is responsible for avoiding deadlock situations.
*/
typedef ptrdiff_t (*libvlc_media_read_cb)(void *opaque, unsigned char *buf,
size_t len);
/**
* Callback prototype to seek a custom bitstream input media.
*
* \param opaque private pointer as set by the @ref libvlc_media_open_cb
* callback
* \param offset absolute byte offset to seek to
* \return 0 on success, -1 on error.
*/
typedef int (*libvlc_media_seek_cb)(void *opaque, uint64_t offset);
/**
* Callback prototype to close a custom bitstream input media.
*
* \param opaque private pointer as set by the @ref libvlc_media_open_cb
* callback
*/
typedef void (*libvlc_media_close_cb)(void *opaque);
/**
* Create a media with a certain given media resource location,
* for instance a valid URL.
*
* \note To refer to a local file with this function,
* the file://... URI syntax <b>must</b> be used (see IETF RFC3986).
* We recommend using libvlc_media_new_path() instead when dealing with
* local files.
*
* \see libvlc_media_release
*
* \param psz_mrl the media location
* \return the newly created media or NULL on error
*/
LIBVLC_API libvlc_media_t *libvlc_media_new_location(const char * psz_mrl);
/**
* Create a media for a certain file path.
*
* \see libvlc_media_release
*
* \param path local filesystem path
* \return the newly created media or NULL on error
*/
LIBVLC_API libvlc_media_t *libvlc_media_new_path(const char *path);
/**
* Create a media for an already open file descriptor.
* The file descriptor shall be open for reading (or reading and writing).
*
* Regular file descriptors, pipe read descriptors and character device
* descriptors (including TTYs) are supported on all platforms.
* Block device descriptors are supported where available.
* Directory descriptors are supported on systems that provide fdopendir().
* Sockets are supported on all platforms where they are file descriptors,
* i.e. all except Windows.
*
* \note This library will <b>not</b> automatically close the file descriptor
* under any circumstance. Nevertheless, a file descriptor can usually only be
* rendered once in a media player. To render it a second time, the file
* descriptor should probably be rewound to the beginning with lseek().
*
* \see libvlc_media_release
*
* \version LibVLC 1.1.5 and later.
*
* \param fd open file descriptor
* \return the newly created media or NULL on error
*/
LIBVLC_API libvlc_media_t *libvlc_media_new_fd(int fd);
/**
* Create a media with custom callbacks to read the data from.
*
* \param open_cb callback to open the custom bitstream input media
* \param read_cb callback to read data (must not be NULL)
* \param seek_cb callback to seek, or NULL if seeking is not supported
* \param close_cb callback to close the media, or NULL if unnecessary
* \param opaque data pointer for the open callback
*
* \return the newly created media or NULL on error
*
* \note If open_cb is NULL, the opaque pointer will be passed to read_cb,
* seek_cb and close_cb, and the stream size will be treated as unknown.
*
* \note The callbacks may be called asynchronously (from another thread).
* A single stream instance need not be reentrant. However the open_cb needs to
* be reentrant if the media is used by multiple player instances.
*
* \warning The callbacks may be used until all or any player instances
* that were supplied the media item are stopped.
*
* \see libvlc_media_release
*
* \version LibVLC 3.0.0 and later.
*/
LIBVLC_API libvlc_media_t *libvlc_media_new_callbacks(
libvlc_media_open_cb open_cb,
libvlc_media_read_cb read_cb,
libvlc_media_seek_cb seek_cb,
libvlc_media_close_cb close_cb,
void *opaque );
/**
* Create a media as an empty node with a given name.
*
* \see libvlc_media_release
*
* \param psz_name the name of the node
* \return the new empty media or NULL on error
*/
LIBVLC_API libvlc_media_t *libvlc_media_new_as_node(const char * psz_name);
/**
* Add an option to the media.
*
* This option will be used to determine how the media_player will
* read the media. This allows to use VLC's advanced
* reading/streaming options on a per-media basis.
*
* \note The options are listed in 'vlc --longhelp' from the command line,
* e.g. "--sout-all". Keep in mind that available options and their semantics
* vary across LibVLC versions and builds.
* \warning Not all options affects libvlc_media_t objects:
* Specifically, due to architectural issues most audio and video options,
* such as text renderer options, have no effects on an individual media.
* These options must be set through libvlc_new() instead.
*
* \param p_md the media descriptor
* \param psz_options the options (as a string)
*/
LIBVLC_API void libvlc_media_add_option(
libvlc_media_t *p_md,
const char * psz_options );
/**
* Add an option to the media with configurable flags.
*
* This option will be used to determine how the media_player will
* read the media. This allows to use VLC's advanced
* reading/streaming options on a per-media basis.
*
* The options are detailed in vlc --longhelp, for instance
* "--sout-all". Note that all options are not usable on medias:
* specifically, due to architectural issues, video-related options
* such as text renderer options cannot be set on a single media. They
* must be set on the whole libvlc instance instead.
*
* \param p_md the media descriptor
* \param psz_options the options (as a string)
* \param i_flags the flags for this option
*/
LIBVLC_API void libvlc_media_add_option_flag(
libvlc_media_t *p_md,
const char * psz_options,
unsigned i_flags );
/**
* Retain a reference to a media descriptor object (libvlc_media_t). Use
* libvlc_media_release() to decrement the reference count of a
* media descriptor object.
*
* \param p_md the media descriptor
* \return the same object
*/
LIBVLC_API libvlc_media_t *libvlc_media_retain( libvlc_media_t *p_md );
/**
* Decrement the reference count of a media descriptor object. If the
* reference count is 0, then libvlc_media_release() will release the
* media descriptor object. If the media descriptor object has been released it
* should not be used again.
*
* \param p_md the media descriptor
*/
LIBVLC_API void libvlc_media_release( libvlc_media_t *p_md );
/**
* Get the media resource locator (mrl) from a media descriptor object
*
* \param p_md a media descriptor object
* \return string with mrl of media descriptor object
*/
LIBVLC_API char *libvlc_media_get_mrl( libvlc_media_t *p_md );
/**
* Duplicate a media descriptor object.
*
* \warning the duplicated media won't share forthcoming updates from the
* original one.
*
* \param p_md a media descriptor object.
*/
LIBVLC_API libvlc_media_t *libvlc_media_duplicate( libvlc_media_t *p_md );
/**
* Read the meta of the media.
*
* Note, you need to call libvlc_media_parse_request() or play the media
* at least once before calling this function.
* If the media has not yet been parsed this will return NULL.
*
* \see libvlc_MediaMetaChanged
*
* \param p_md the media descriptor
* \param e_meta the meta to read
* \return the media's meta
*/
LIBVLC_API char *libvlc_media_get_meta( libvlc_media_t *p_md,
libvlc_meta_t e_meta );
/**
* Set the meta of the media (this function will not save the meta, call
* libvlc_media_save_meta in order to save the meta)
*
* \param p_md the media descriptor
* \param e_meta the meta to write
* \param psz_value the media's meta
*/
LIBVLC_API void libvlc_media_set_meta( libvlc_media_t *p_md,
libvlc_meta_t e_meta,
const char *psz_value );
/**
* Read the meta extra of the media.
*
* If the media has not yet been parsed this will return NULL.
*
* \see libvlc_media_parse
* \see libvlc_media_parse_with_options
*
* \param p_md the media descriptor
* \param psz_name the meta extra to read (nonnullable)
* \return the media's meta extra or NULL
*/
LIBVLC_API char *libvlc_media_get_meta_extra( libvlc_media_t *p_md,
const char *psz_name );
/**
* Set the meta of the media (this function will not save the meta, call
* libvlc_media_save_meta in order to save the meta)
*
* \param p_md the media descriptor
* \param psz_name the meta extra to write (nonnullable)
* \param psz_value the media's meta extra (nullable)
* Removed from meta extra if set to NULL
*/
LIBVLC_API void libvlc_media_set_meta_extra( libvlc_media_t *p_md,
const char *psz_name,
const char *psz_value );
/**
* Read the meta extra names of the media.
*
* \param p_md the media descriptor
* \param pppsz_names the media's meta extra name array
* you can access the elements using the return value (count)
* must be released with libvlc_media_meta_extra_names_release()
* \return the meta extra count
*/
LIBVLC_API unsigned libvlc_media_get_meta_extra_names( libvlc_media_t *p_md,
char ***pppsz_names );
/**
* Release a media meta extra names
*
* \param ppsz_names meta extra names array to release
* \param i_count number of elements in the array
*/
LIBVLC_API void libvlc_media_meta_extra_names_release( char **ppsz_names,
unsigned i_count );
/**
* Save the meta previously set
*
* \param inst LibVLC instance
* \param p_md the media descriptor
* \return true if the write operation was successful
*/
LIBVLC_API int libvlc_media_save_meta( libvlc_instance_t *inst,
libvlc_media_t *p_md );
/**
* Get the current statistics about the media
* \param p_md media descriptor object
* \param p_stats structure that contain the statistics about the media
* (this structure must be allocated by the caller)
* \retval true statistics are available
* \retval false otherwise
*/
LIBVLC_API bool libvlc_media_get_stats(libvlc_media_t *p_md,
libvlc_media_stats_t *p_stats);
/* The following method uses libvlc_media_list_t, however, media_list usage is optional
* and this is here for convenience */
#define VLC_FORWARD_DECLARE_OBJECT(a) struct a
/**
* Get subitems of media descriptor object. This will increment
* the reference count of supplied media descriptor object. Use
* libvlc_media_list_release() to decrement the reference counting.
*
* \param p_md media descriptor object
* \return list of media descriptor subitems or NULL
*/
LIBVLC_API VLC_FORWARD_DECLARE_OBJECT(libvlc_media_list_t *)
libvlc_media_subitems( libvlc_media_t *p_md );
/**
* Get event manager from media descriptor object.
* NOTE: this function doesn't increment reference counting.
*
* \param p_md a media descriptor object
* \return event manager object
*/
LIBVLC_API libvlc_event_manager_t *
libvlc_media_event_manager( libvlc_media_t *p_md );
/**
* Get duration (in ms) of media descriptor object item.
*
* Note, you need to call libvlc_media_parse_request() or play the media
* at least once before calling this function.
* Not doing this will result in an undefined result.
*
* \param p_md media descriptor object
* \return duration of media item or -1 on error
*/
LIBVLC_API libvlc_time_t
libvlc_media_get_duration( libvlc_media_t *p_md );
/**
* Get a 'stat' value of media descriptor object item.
*
* \note 'stat' values are currently only parsed by directory accesses. This
* mean that only sub medias of a directory media, parsed with
* libvlc_media_parse_request() can have valid 'stat' properties.
* \version LibVLC 4.0.0 and later.
*
* \param p_md media descriptor object
* \param type a valid libvlc_media_stat_ define
* \param out field in which the value will be stored
* \return 1 on success, 0 if not found, -1 on error.
*/
LIBVLC_API int
libvlc_media_get_filestat( libvlc_media_t *p_md, unsigned type, uint64_t *out );
/**
* Parse the media asynchronously with options.
*
* This fetches (local or network) art, meta data and/or tracks information.
*
* To track when this is over you can listen to libvlc_MediaParsedChanged
* event. However if this functions returns an error, you will not receive any
* events.
*
* It uses a flag to specify parse options (see libvlc_media_parse_flag_t). All
* these flags can be combined. By default, media is parsed if it's a local
* file.
*
* \note Parsing can be aborted with libvlc_media_parse_stop().
*
* \see libvlc_MediaParsedChanged
* \see libvlc_media_get_meta
* \see libvlc_media_get_tracklist
* \see libvlc_media_get_parsed_status
* \see libvlc_media_parse_flag_t
*
* \param inst LibVLC instance that is to parse the media
* \param p_md media descriptor object
* \param parse_flag parse options:
* \param timeout maximum time allowed to preparse the media. If -1, the
* default "preparse-timeout" option will be used as a timeout. If 0, it will
* wait indefinitely. If > 0, the timeout will be used (in milliseconds).
* \return -1 in case of error, 0 otherwise
* \version LibVLC 4.0.0 or later
*/
LIBVLC_API int
libvlc_media_parse_request( libvlc_instance_t *inst, libvlc_media_t *p_md,
libvlc_media_parse_flag_t parse_flag,
int timeout );
/**
* Stop the parsing of the media
*
* When the media parsing is stopped, the libvlc_MediaParsedChanged event will
* be sent with the libvlc_media_parsed_status_timeout status.
*
* \see libvlc_media_parse_request()
*
* \param inst LibVLC instance that is to cease or give up parsing the media
* \param p_md media descriptor object
* \version LibVLC 3.0.0 or later
*/
LIBVLC_API void
libvlc_media_parse_stop( libvlc_instance_t *inst, libvlc_media_t *p_md );
/**
* Get Parsed status for media descriptor object.
*
* \see libvlc_MediaParsedChanged
* \see libvlc_media_parsed_status_t
* \see libvlc_media_parse_request()
*
* \param p_md media descriptor object
* \return a value of the libvlc_media_parsed_status_t enum
* \version LibVLC 3.0.0 or later
*/
LIBVLC_API libvlc_media_parsed_status_t
libvlc_media_get_parsed_status( libvlc_media_t *p_md );
/**
* Sets media descriptor's user_data. user_data is specialized data
* accessed by the host application, VLC.framework uses it as a pointer to
* an native object that references a libvlc_media_t pointer
*
* \param p_md media descriptor object
* \param p_new_user_data pointer to user data
*/
LIBVLC_API void
libvlc_media_set_user_data( libvlc_media_t *p_md, void *p_new_user_data );
/**
* Get media descriptor's user_data. user_data is specialized data
* accessed by the host application, VLC.framework uses it as a pointer to
* an native object that references a libvlc_media_t pointer
*
* \see libvlc_media_set_user_data
*
* \param p_md media descriptor object
*/
LIBVLC_API void *libvlc_media_get_user_data( libvlc_media_t *p_md );
/**
* Get the track list for one type
*
* \version LibVLC 4.0.0 and later.
*
* \note You need to call libvlc_media_parse_request() or play the media
* at least once before calling this function. Not doing this will result in
* an empty list.
*
* \see libvlc_media_tracklist_count
* \see libvlc_media_tracklist_at
*
* \param p_md media descriptor object
* \param type type of the track list to request
*
* \return a valid libvlc_media_tracklist_t or NULL in case of error, if there
* is no track for a category, the returned list will have a size of 0, delete
* with libvlc_media_tracklist_delete()
*/
LIBVLC_API libvlc_media_tracklist_t *
libvlc_media_get_tracklist( libvlc_media_t *p_md, libvlc_track_type_t type );
/**
* Get codec description from media elementary stream
*
* Note, you need to call libvlc_media_parse_request() or play the media
* at least once before calling this function.
*
* \version LibVLC 3.0.0 and later.
*
* \see libvlc_media_track_t
*
* \param i_type i_type from libvlc_media_track_t
* \param i_codec i_codec or i_original_fourcc from libvlc_media_track_t
*
* \return codec description
*/
LIBVLC_API
const char *libvlc_media_get_codec_description( libvlc_track_type_t i_type,
uint32_t i_codec );
/**
* Get the media type of the media descriptor object
*
* \version LibVLC 3.0.0 and later.
*
* \see libvlc_media_type_t
*
* \param p_md media descriptor object
*
* \return media type
*/
LIBVLC_API
libvlc_media_type_t libvlc_media_get_type( libvlc_media_t *p_md );
/**
* \brief libvlc_media_thumbnail_request_t An opaque thumbnail request object
*/
typedef struct libvlc_media_thumbnail_request_t libvlc_media_thumbnail_request_t;
typedef enum libvlc_thumbnailer_seek_speed_t
{
libvlc_media_thumbnail_seek_precise,
libvlc_media_thumbnail_seek_fast,
} libvlc_thumbnailer_seek_speed_t;
/**
* \brief libvlc_media_request_thumbnail_by_time Start an asynchronous thumbnail generation
*
* If the request is successfully queued, the libvlc_MediaThumbnailGenerated is
* guaranteed to be emitted (except if the request is destroyed early by the
* user).
* The resulting thumbnail size can either be:
* - Hardcoded by providing both width & height. In which case, the image will
* be stretched to match the provided aspect ratio, or cropped if crop is true.
* - Derived from the media aspect ratio if only width or height is provided and
* the other one is set to 0.
*
* \param inst LibVLC instance to generate the thumbnail with
* \param md media descriptor object
* \param time The time at which the thumbnail should be generated
* \param speed The seeking speed \sa{libvlc_thumbnailer_seek_speed_t}
* \param width The thumbnail width
* \param height the thumbnail height
* \param crop Should the picture be cropped to preserve source aspect ratio
* \param picture_type The thumbnail picture type \sa{libvlc_picture_type_t}
* \param timeout A timeout value in ms, or 0 to disable timeout
*
* \return A valid opaque request object, or NULL in case of failure.
* It must be released by libvlc_media_thumbnail_request_destroy() and
* can be cancelled by calling it early.
*
* \version libvlc 4.0 or later
*
* \see libvlc_picture_t
* \see libvlc_picture_type_t
*/
LIBVLC_API libvlc_media_thumbnail_request_t*
libvlc_media_thumbnail_request_by_time( libvlc_instance_t *inst,
libvlc_media_t *md, libvlc_time_t time,
libvlc_thumbnailer_seek_speed_t speed,
unsigned int width, unsigned int height,
bool crop, libvlc_picture_type_t picture_type,
libvlc_time_t timeout );
/**
* \brief libvlc_media_request_thumbnail_by_pos Start an asynchronous thumbnail generation
*
* If the request is successfully queued, the libvlc_MediaThumbnailGenerated is
* guaranteed to be emitted (except if the request is destroyed early by the
* user).
* The resulting thumbnail size can either be:
* - Hardcoded by providing both width & height. In which case, the image will
* be stretched to match the provided aspect ratio, or cropped if crop is true.
* - Derived from the media aspect ratio if only width or height is provided and
* the other one is set to 0.
*
* \param inst LibVLC instance to generate the thumbnail with
* \param md media descriptor object
* \param pos The position at which the thumbnail should be generated
* \param speed The seeking speed \sa{libvlc_thumbnailer_seek_speed_t}
* \param width The thumbnail width
* \param height the thumbnail height
* \param crop Should the picture be cropped to preserve source aspect ratio
* \param picture_type The thumbnail picture type \sa{libvlc_picture_type_t}
* \param timeout A timeout value in ms, or 0 to disable timeout
*
* \return A valid opaque request object, or NULL in case of failure.
* It must be released by libvlc_media_thumbnail_request_destroy().
*
* \version libvlc 4.0 or later
*
* \see libvlc_picture_t
* \see libvlc_picture_type_t
*/
LIBVLC_API libvlc_media_thumbnail_request_t*
libvlc_media_thumbnail_request_by_pos( libvlc_instance_t *inst,
libvlc_media_t *md, double pos,
libvlc_thumbnailer_seek_speed_t speed,
unsigned int width, unsigned int height,
bool crop, libvlc_picture_type_t picture_type,
libvlc_time_t timeout );
/**
* @brief libvlc_media_thumbnail_destroy destroys a thumbnail request
* @param p_req An opaque thumbnail request object.
*
* This will also cancel the thumbnail request, no events will be emitted after
* this call.
*/
LIBVLC_API void
libvlc_media_thumbnail_request_destroy( libvlc_media_thumbnail_request_t *p_req );
/**
* Add a slave to the current media.
*
* A slave is an external input source that may contains an additional subtitle
* track (like a .srt) or an additional audio track (like a .ac3).
*
* \note This function must be called before the media is parsed (via
* libvlc_media_parse_request()) or before the media is played (via
* libvlc_media_player_play())
*
* \version LibVLC 3.0.0 and later.
*
* \param p_md media descriptor object
* \param i_type subtitle or audio
* \param i_priority from 0 (low priority) to 4 (high priority)
* \param psz_uri Uri of the slave (should contain a valid scheme).
*
* \return 0 on success, -1 on error.
*/
LIBVLC_API
int libvlc_media_slaves_add( libvlc_media_t *p_md,
libvlc_media_slave_type_t i_type,
unsigned int i_priority,
const char *psz_uri );
/**
* Clear all slaves previously added by libvlc_media_slaves_add() or
* internally.
*
* \version LibVLC 3.0.0 and later.
*
* \param p_md media descriptor object
*/
LIBVLC_API
void libvlc_media_slaves_clear( libvlc_media_t *p_md );
/**
* Get a media descriptor's slave list
*
* The list will contain slaves parsed by VLC or previously added by
* libvlc_media_slaves_add(). The typical use case of this function is to save
* a list of slave in a database for a later use.
*
* \version LibVLC 3.0.0 and later.
*
* \see libvlc_media_slaves_add
*
* \param p_md media descriptor object
* \param ppp_slaves address to store an allocated array of slaves (must be
* freed with libvlc_media_slaves_release()) [OUT]
*
* \return the number of slaves (zero on error)
*/
LIBVLC_API
unsigned int libvlc_media_slaves_get( libvlc_media_t *p_md,
libvlc_media_slave_t ***ppp_slaves );
/**
* Release a media descriptor's slave list
*
* \version LibVLC 3.0.0 and later.
*
* \param pp_slaves slave array to release
* \param i_count number of elements in the array
*/
LIBVLC_API
void libvlc_media_slaves_release( libvlc_media_slave_t **pp_slaves,
unsigned int i_count );
/** @}*/
# ifdef __cplusplus
}
# endif
#endif /* VLC_LIBVLC_MEDIA_H */

View file

@ -0,0 +1,188 @@
/*****************************************************************************
* libvlc_media_discoverer.h: libvlc external API
*****************************************************************************
* Copyright (C) 1998-2009 VLC authors and VideoLAN
*
* Authors: Clément Stenac <zorglub@videolan.org>
* Jean-Paul Saman <jpsaman@videolan.org>
* Pierre d'Herbemont <pdherbemont@videolan.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_LIBVLC_MEDIA_DISCOVERER_H
#define VLC_LIBVLC_MEDIA_DISCOVERER_H 1
# ifdef __cplusplus
extern "C" {
# endif
typedef struct libvlc_media_list_t libvlc_media_list_t;
/**
* Category of a media discoverer
* \see libvlc_media_discoverer_list_get()
*/
typedef enum libvlc_media_discoverer_category_t {
/** devices, like portable music player */
libvlc_media_discoverer_devices,
/** LAN/WAN services, like Upnp, SMB, or SAP */
libvlc_media_discoverer_lan,
/** Podcasts */
libvlc_media_discoverer_podcasts,
/** Local directories, like Video, Music or Pictures directories */
libvlc_media_discoverer_localdirs,
} libvlc_media_discoverer_category_t;
/**
* Media discoverer description
* \see libvlc_media_discoverer_list_get()
*/
typedef struct libvlc_media_discoverer_description_t {
char *psz_name;
char *psz_longname;
libvlc_media_discoverer_category_t i_cat;
} libvlc_media_discoverer_description_t;
/** \defgroup libvlc_media_discoverer LibVLC media discovery
* \ingroup libvlc
* LibVLC media discovery finds available media via various means.
* This corresponds to the service discovery functionality in VLC media player.
* Different plugins find potential medias locally (e.g. user media directory),
* from peripherals (e.g. video capture device), on the local network
* (e.g. SAP) or on the Internet (e.g. Internet radios).
* @{
* \file
* LibVLC media discovery external API
*/
typedef struct libvlc_media_discoverer_t libvlc_media_discoverer_t;
/**
* Create a media discoverer object by name.
*
* After this object is created, you should attach to media_list events in
* order to be notified of new items discovered.
*
* You need to call libvlc_media_discoverer_start() in order to start the
* discovery.
*
* \see libvlc_media_discoverer_media_list
* \see libvlc_media_discoverer_start
*
* \param p_inst libvlc instance
* \param psz_name service name; use libvlc_media_discoverer_list_get() to get
* a list of the discoverer names available in this libVLC instance
* \return media discover object or NULL in case of error
* \version LibVLC 3.0.0 or later
*/
LIBVLC_API libvlc_media_discoverer_t *
libvlc_media_discoverer_new( libvlc_instance_t * p_inst,
const char * psz_name );
/**
* Start media discovery.
*
* To stop it, call libvlc_media_discoverer_stop() or
* libvlc_media_discoverer_list_release() directly.
*
* \see libvlc_media_discoverer_stop
*
* \param p_mdis media discover object
* \return -1 in case of error, 0 otherwise
* \version LibVLC 3.0.0 or later
*/
LIBVLC_API int
libvlc_media_discoverer_start( libvlc_media_discoverer_t * p_mdis );
/**
* Stop media discovery.
*
* \see libvlc_media_discoverer_start
*
* \param p_mdis media discover object
* \version LibVLC 3.0.0 or later
*/
LIBVLC_API void
libvlc_media_discoverer_stop( libvlc_media_discoverer_t * p_mdis );
/**
* Release media discover object. If the reference count reaches 0, then
* the object will be released.
*
* \param p_mdis media service discover object
*/
LIBVLC_API void
libvlc_media_discoverer_release( libvlc_media_discoverer_t * p_mdis );
/**
* Get media service discover media list.
*
* \param p_mdis media service discover object
* \return list of media items
*/
LIBVLC_API libvlc_media_list_t *
libvlc_media_discoverer_media_list( libvlc_media_discoverer_t * p_mdis );
/**
* Query if media service discover object is running.
*
* \param p_mdis media service discover object
*
* \retval true running
* \retval false not running
*/
LIBVLC_API bool
libvlc_media_discoverer_is_running(libvlc_media_discoverer_t *p_mdis);
/**
* Get media discoverer services by category
*
* \version LibVLC 3.0.0 and later.
*
* \param p_inst libvlc instance
* \param i_cat category of services to fetch
* \param ppp_services address to store an allocated array of media discoverer
* services (must be freed with libvlc_media_discoverer_list_release() by
* the caller) [OUT]
*
* \return the number of media discoverer services (0 on error)
*/
LIBVLC_API size_t
libvlc_media_discoverer_list_get( libvlc_instance_t *p_inst,
libvlc_media_discoverer_category_t i_cat,
libvlc_media_discoverer_description_t ***ppp_services );
/**
* Release an array of media discoverer services
*
* \version LibVLC 3.0.0 and later.
*
* \see libvlc_media_discoverer_list_get()
*
* \param pp_services array to release
* \param i_count number of elements in the array
*/
LIBVLC_API void
libvlc_media_discoverer_list_release( libvlc_media_discoverer_description_t **pp_services,
size_t i_count );
/**@} */
# ifdef __cplusplus
}
# endif
#endif /* <vlc/libvlc.h> */

View file

@ -0,0 +1,200 @@
/*****************************************************************************
* libvlc_media_list.h: libvlc_media_list API
*****************************************************************************
* Copyright (C) 1998-2008 VLC authors and VideoLAN
*
* Authors: Pierre d'Herbemont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef LIBVLC_MEDIA_LIST_H
#define LIBVLC_MEDIA_LIST_H 1
typedef struct libvlc_media_t libvlc_media_t;
# ifdef __cplusplus
extern "C" {
# endif
/** \defgroup libvlc_media_list LibVLC media list
* \ingroup libvlc
* A LibVLC media list holds multiple @ref libvlc_media_t media descriptors.
* @{
* \file
* LibVLC media list (playlist) external API
*/
typedef struct libvlc_media_list_t libvlc_media_list_t;
/**
* Create an empty media list.
*
* \return empty media list, or NULL on error
*/
LIBVLC_API libvlc_media_list_t *libvlc_media_list_new(void);
/**
* Release media list created with libvlc_media_list_new().
*
* \param p_ml a media list created with libvlc_media_list_new()
*/
LIBVLC_API void
libvlc_media_list_release( libvlc_media_list_t *p_ml );
/**
* Retain reference to a media list
*
* \param p_ml a media list created with libvlc_media_list_new()
* \return the same object
*/
LIBVLC_API libvlc_media_list_t *
libvlc_media_list_retain( libvlc_media_list_t *p_ml );
/**
* Associate media instance with this media list instance.
* If another media instance was present it will be released.
* The libvlc_media_list_lock should NOT be held upon entering this function.
*
* \param p_ml a media list instance
* \param p_md media instance to add
*/
LIBVLC_API void
libvlc_media_list_set_media( libvlc_media_list_t *p_ml, libvlc_media_t *p_md );
/**
* Get media instance from this media list instance. This action will increase
* the refcount on the media instance.
* The libvlc_media_list_lock should NOT be held upon entering this function.
*
* \param p_ml a media list instance
* \return media instance
*/
LIBVLC_API libvlc_media_t *
libvlc_media_list_media( libvlc_media_list_t *p_ml );
/**
* Add media instance to media list
* The libvlc_media_list_lock should be held upon entering this function.
*
* \param p_ml a media list instance
* \param p_md a media instance
* \return 0 on success, -1 if the media list is read-only
*/
LIBVLC_API int
libvlc_media_list_add_media( libvlc_media_list_t *p_ml, libvlc_media_t *p_md );
/**
* Insert media instance in media list on a position
* The libvlc_media_list_lock should be held upon entering this function.
*
* \param p_ml a media list instance
* \param p_md a media instance
* \param i_pos position in array where to insert
* \return 0 on success, -1 if the media list is read-only
*/
LIBVLC_API int
libvlc_media_list_insert_media( libvlc_media_list_t *p_ml,
libvlc_media_t *p_md, int i_pos );
/**
* Remove media instance from media list on a position
* The libvlc_media_list_lock should be held upon entering this function.
*
* \param p_ml a media list instance
* \param i_pos position in array where to insert
* \return 0 on success, -1 if the list is read-only or the item was not found
*/
LIBVLC_API int
libvlc_media_list_remove_index( libvlc_media_list_t *p_ml, int i_pos );
/**
* Get count on media list items
* The libvlc_media_list_lock should be held upon entering this function.
*
* \param p_ml a media list instance
* \return number of items in media list
*/
LIBVLC_API int
libvlc_media_list_count( libvlc_media_list_t *p_ml );
/**
* List media instance in media list at a position
* The libvlc_media_list_lock should be held upon entering this function.
*
* \param p_ml a media list instance
* \param i_pos position in array where to insert
* \return media instance at position i_pos, or NULL if not found.
* In case of success, libvlc_media_retain() is called to increase the refcount
* on the media.
*/
LIBVLC_API libvlc_media_t *
libvlc_media_list_item_at_index( libvlc_media_list_t *p_ml, int i_pos );
/**
* Find index position of List media instance in media list.
* Warning: the function will return the first matched position.
* The libvlc_media_list_lock should be held upon entering this function.
*
* \param p_ml a media list instance
* \param p_md media instance
* \return position of media instance or -1 if media not found
*/
LIBVLC_API int
libvlc_media_list_index_of_item( libvlc_media_list_t *p_ml,
libvlc_media_t *p_md );
/**
* This indicates if this media list is read-only from a user point of view
*
* \param p_ml media list instance
* \retval true read-only
* \retval false read/write
*/
LIBVLC_API bool libvlc_media_list_is_readonly(libvlc_media_list_t *p_ml);
/**
* Get lock on media list items
*
* \param p_ml a media list instance
*/
LIBVLC_API void
libvlc_media_list_lock( libvlc_media_list_t *p_ml );
/**
* Release lock on media list items
* The libvlc_media_list_lock should be held upon entering this function.
*
* \param p_ml a media list instance
*/
LIBVLC_API void
libvlc_media_list_unlock( libvlc_media_list_t *p_ml );
/**
* Get libvlc_event_manager from this media list instance.
* The p_event_manager is immutable, so you don't have to hold the lock
*
* \param p_ml a media list instance
* \return libvlc_event_manager
*/
LIBVLC_API libvlc_event_manager_t *
libvlc_media_list_event_manager( libvlc_media_list_t *p_ml );
/** @} media_list */
# ifdef __cplusplus
}
# endif
#endif /* _LIBVLC_MEDIA_LIST_H */

View file

@ -0,0 +1,249 @@
/*****************************************************************************
* libvlc_media_list_player.h: libvlc_media_list API
*****************************************************************************
* Copyright (C) 1998-2008 VLC authors and VideoLAN
*
* Authors: Pierre d'Herbemont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef LIBVLC_MEDIA_LIST_PLAYER_H
#define LIBVLC_MEDIA_LIST_PLAYER_H 1
#include <vlc/libvlc.h>
#include <vlc/libvlc_media.h>
# ifdef __cplusplus
extern "C" {
# endif
typedef struct libvlc_instance_t libvlc_instance_t;
typedef struct libvlc_media_player_t libvlc_media_player_t;
typedef struct libvlc_media_list_t libvlc_media_list_t;
typedef struct libvlc_media_t libvlc_media_t;
/** \defgroup libvlc_media_list_player LibVLC media list player
* \ingroup libvlc
* The LibVLC media list player plays a @ref libvlc_media_list_t list of media,
* in a certain order.
* This is required to especially support playlist files.
* The normal @ref libvlc_media_player_t LibVLC media player can only play a
* single media, and does not handle playlist files properly.
* @{
* \file
* LibVLC media list player external API
*/
typedef struct libvlc_media_list_player_t libvlc_media_list_player_t;
/**
* Defines playback modes for playlist.
*/
typedef enum libvlc_playback_mode_t
{
libvlc_playback_mode_default,
libvlc_playback_mode_loop,
libvlc_playback_mode_repeat
} libvlc_playback_mode_t;
/**
* Create new media_list_player.
*
* \param p_instance libvlc instance
* \return media list player instance or NULL on error
* (it must be released by libvlc_media_list_player_release())
*/
LIBVLC_API libvlc_media_list_player_t *
libvlc_media_list_player_new( libvlc_instance_t * p_instance );
/**
* Release a media_list_player after use
* Decrement the reference count of a media player object. If the
* reference count is 0, then libvlc_media_list_player_release() will
* release the media player object. If the media player object
* has been released, then it should not be used again.
*
* \param p_mlp media list player instance
*/
LIBVLC_API void
libvlc_media_list_player_release( libvlc_media_list_player_t * p_mlp );
/**
* Retain a reference to a media player list object. Use
* libvlc_media_list_player_release() to decrement reference count.
*
* \param p_mlp media player list object
* \return the same object
*/
LIBVLC_API libvlc_media_list_player_t *
libvlc_media_list_player_retain( libvlc_media_list_player_t *p_mlp );
/**
* Return the event manager of this media_list_player.
*
* \param p_mlp media list player instance
* \return the event manager
*/
LIBVLC_API libvlc_event_manager_t *
libvlc_media_list_player_event_manager(libvlc_media_list_player_t * p_mlp);
/**
* Replace media player in media_list_player with this instance.
*
* \param p_mlp media list player instance
* \param p_mi media player instance
*/
LIBVLC_API void
libvlc_media_list_player_set_media_player(
libvlc_media_list_player_t * p_mlp,
libvlc_media_player_t * p_mi );
/**
* Get media player of the media_list_player instance.
*
* \param p_mlp media list player instance
* \return media player instance
* \note the caller is responsible for releasing the returned instance
with libvlc_media_list_player_set_media_player().
*/
LIBVLC_API libvlc_media_player_t *
libvlc_media_list_player_get_media_player(libvlc_media_list_player_t * p_mlp);
/**
* Set the media list associated with the player
*
* \param p_mlp media list player instance
* \param p_mlist list of media
*/
LIBVLC_API void
libvlc_media_list_player_set_media_list(
libvlc_media_list_player_t * p_mlp,
libvlc_media_list_t * p_mlist );
/**
* Play media list
*
* \param p_mlp media list player instance
*/
LIBVLC_API
void libvlc_media_list_player_play(libvlc_media_list_player_t * p_mlp);
/**
* Toggle pause (or resume) media list
*
* \param p_mlp media list player instance
*/
LIBVLC_API
void libvlc_media_list_player_pause(libvlc_media_list_player_t * p_mlp);
/**
* Pause or resume media list
*
* \param p_mlp media list player instance
* \param do_pause play/resume if zero, pause if non-zero
* \version LibVLC 3.0.0 or later
*/
LIBVLC_API
void libvlc_media_list_player_set_pause(libvlc_media_list_player_t * p_mlp,
int do_pause);
/**
* Is media list playing?
*
* \param p_mlp media list player instance
*
* \retval true playing
* \retval false not playing
*/
LIBVLC_API bool
libvlc_media_list_player_is_playing(libvlc_media_list_player_t * p_mlp);
/**
* Get current libvlc_state of media list player
*
* \param p_mlp media list player instance
* \return libvlc_state_t for media list player
*/
LIBVLC_API libvlc_state_t
libvlc_media_list_player_get_state( libvlc_media_list_player_t * p_mlp );
/**
* Play media list item at position index
*
* \param p_mlp media list player instance
* \param i_index index in media list to play
* \return 0 upon success -1 if the item wasn't found
*/
LIBVLC_API
int libvlc_media_list_player_play_item_at_index(libvlc_media_list_player_t * p_mlp,
int i_index);
/**
* Play the given media item
*
* \param p_mlp media list player instance
* \param p_md the media instance
* \return 0 upon success, -1 if the media is not part of the media list
*/
LIBVLC_API
int libvlc_media_list_player_play_item(libvlc_media_list_player_t * p_mlp,
libvlc_media_t * p_md);
/**
* Stop playing media list
*
* \param p_mlp media list player instance
*/
LIBVLC_API void
libvlc_media_list_player_stop_async( libvlc_media_list_player_t * p_mlp);
/**
* Play next item from media list
*
* \param p_mlp media list player instance
* \return 0 upon success -1 if there is no next item
*/
LIBVLC_API
int libvlc_media_list_player_next(libvlc_media_list_player_t * p_mlp);
/**
* Play previous item from media list
*
* \param p_mlp media list player instance
* \return 0 upon success -1 if there is no previous item
*/
LIBVLC_API
int libvlc_media_list_player_previous(libvlc_media_list_player_t * p_mlp);
/**
* Sets the playback mode for the playlist
*
* \param p_mlp media list player instance
* \param e_mode playback mode specification
*/
LIBVLC_API
void libvlc_media_list_player_set_playback_mode(libvlc_media_list_player_t * p_mlp,
libvlc_playback_mode_t e_mode );
/** @} media_list_player */
# ifdef __cplusplus
}
# endif
#endif /* LIBVLC_MEDIA_LIST_PLAYER_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,212 @@
/*****************************************************************************
* libvlc_media_track.h: libvlc external API
*****************************************************************************
* Copyright (C) 1998-2020 VLC authors and VideoLAN
*
* Authors: Clément Stenac <zorglub@videolan.org>
* Jean-Paul Saman <jpsaman@videolan.org>
* Pierre d'Herbemont <pdherbemont@videolan.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_LIBVLC_MEDIA_TRACK_H
#define VLC_LIBVLC_MEDIA_TRACK_H 1
# include "libvlc_video.h"
# ifdef __cplusplus
extern "C" {
# else
# include <stdbool.h>
# endif
/** \defgroup libvlc_media_track LibVLC media track
* \ingroup libvlc
* @ref libvlc_media_track_t is an abstract representation of a media track.
* @{
* \file
* LibVLC media track
*/
typedef enum libvlc_track_type_t
{
libvlc_track_unknown = -1,
libvlc_track_audio = 0,
libvlc_track_video = 1,
libvlc_track_text = 2
} libvlc_track_type_t;
typedef struct libvlc_audio_track_t
{
unsigned i_channels;
unsigned i_rate;
} libvlc_audio_track_t;
/**
* Viewpoint
*
* \warning allocate using libvlc_video_new_viewpoint()
*/
typedef struct libvlc_video_viewpoint_t
{
float f_yaw; /**< view point yaw in degrees ]-180;180] */
float f_pitch; /**< view point pitch in degrees ]-90;90] */
float f_roll; /**< view point roll in degrees ]-180;180] */
float f_field_of_view; /**< field of view in degrees ]0;180[ (default 80.)*/
} libvlc_video_viewpoint_t;
typedef struct libvlc_video_track_t
{
unsigned i_height;
unsigned i_width;
unsigned i_sar_num;
unsigned i_sar_den;
unsigned i_frame_rate_num;
unsigned i_frame_rate_den;
libvlc_video_orient_t i_orientation;
libvlc_video_projection_t i_projection;
libvlc_video_viewpoint_t pose; /**< Initial view point */
libvlc_video_multiview_t i_multiview;
} libvlc_video_track_t;
typedef struct libvlc_subtitle_track_t
{
char *psz_encoding;
} libvlc_subtitle_track_t;
typedef struct libvlc_media_track_t
{
/* Codec fourcc */
uint32_t i_codec;
uint32_t i_original_fourcc;
int i_id; /* DEPRECATED: use psz_id */
libvlc_track_type_t i_type;
/* Codec specific */
int i_profile;
int i_level;
union {
libvlc_audio_track_t *audio;
libvlc_video_track_t *video;
libvlc_subtitle_track_t *subtitle;
};
unsigned int i_bitrate;
char *psz_language;
char *psz_description;
/** String identifier of track, can be used to save the track preference
* from an other LibVLC run */
const char *psz_id;
/** A string identifier is stable when it is certified to be the same
* across different playback instances for the same track. */
bool id_stable;
/** Name of the track, only valid when the track is fetch from a
* media_player */
char *psz_name;
/** true if the track is selected, only valid when the track is fetch from
* a media_player */
bool selected;
} libvlc_media_track_t;
/**
* Opaque struct containing a list of tracks
*/
typedef struct libvlc_media_tracklist_t libvlc_media_tracklist_t;
/**
* Get the number of tracks in a tracklist
*
* \version LibVLC 4.0.0 and later.
*
* \param list valid tracklist
*
* \return number of tracks, or 0 if the list is empty
*/
LIBVLC_API size_t
libvlc_media_tracklist_count( const libvlc_media_tracklist_t *list );
/**
* Get a track at a specific index
*
* \warning The behaviour is undefined if the index is not valid.
*
* \version LibVLC 4.0.0 and later.
*
* \param list valid tracklist
* \param index valid index in the range [0; count[
*
* \return a valid track (can't be NULL if libvlc_media_tracklist_count()
* returned a valid count)
*/
LIBVLC_API libvlc_media_track_t *
libvlc_media_tracklist_at( libvlc_media_tracklist_t *list, size_t index );
/**
* Release a tracklist
*
* \version LibVLC 4.0.0 and later.
*
* \see libvlc_media_get_tracklist
* \see libvlc_media_player_get_tracklist
*
* \param list valid tracklist
*/
LIBVLC_API void
libvlc_media_tracklist_delete( libvlc_media_tracklist_t *list );
/**
* Hold a single track reference
*
* \version LibVLC 4.0.0 and later.
*
* This function can be used to hold a track from a tracklist. In that case,
* the track can outlive its tracklist.
*
* \param track valid track
* \return the same track, need to be released with libvlc_media_track_release()
*/
LIBVLC_API libvlc_media_track_t *
libvlc_media_track_hold( libvlc_media_track_t *track );
/**
* Release a single track
*
* \version LibVLC 4.0.0 and later.
*
* \warning Tracks from a tracklist are released alongside the list with
* libvlc_media_tracklist_delete().
*
* \note You only need to release tracks previously held with
* libvlc_media_track_hold() or returned by
* libvlc_media_player_get_selected_track() and
* libvlc_media_player_get_track_from_id()
*
* \param track valid track
*/
LIBVLC_API void
libvlc_media_track_release( libvlc_media_track_t *track );
/** @}*/
# ifdef __cplusplus
}
# endif
#endif /* VLC_LIBVLC_MEDIA_TRACK_H */

151
Libs/vlc/libvlc_picture.h Normal file
View file

@ -0,0 +1,151 @@
/*****************************************************************************
* libvlc_picture.h: libvlc external API
*****************************************************************************
* Copyright (C) 2018 VLC authors and VideoLAN
*
* Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_LIBVLC_PICTURE_H
#define VLC_LIBVLC_PICTURE_H 1
# ifdef __cplusplus
extern "C" {
# endif
typedef struct libvlc_picture_t libvlc_picture_t;
typedef struct libvlc_picture_list_t libvlc_picture_list_t;
typedef enum libvlc_picture_type_t
{
libvlc_picture_Argb,
libvlc_picture_Png,
libvlc_picture_Jpg,
libvlc_picture_WebP,
} libvlc_picture_type_t;
/**
* Increment the reference count of this picture.
*
* \see libvlc_picture_release()
* \param pic A picture object
* \return the same object
*/
LIBVLC_API libvlc_picture_t *
libvlc_picture_retain( libvlc_picture_t* pic );
/**
* Decrement the reference count of this picture.
* When the reference count reaches 0, the picture will be released.
* The picture must not be accessed after calling this function.
*
* \see libvlc_picture_retain
* \param pic A picture object
*/
LIBVLC_API void
libvlc_picture_release( libvlc_picture_t* pic );
/**
* Saves this picture to a file. The image format is the same as the one
* returned by \link libvlc_picture_type \endlink
*
* \param pic A picture object
* \param path The path to the generated file
* \return 0 in case of success, -1 otherwise
*/
LIBVLC_API int
libvlc_picture_save( const libvlc_picture_t* pic, const char* path );
/**
* Returns the image internal buffer, including potential padding.
* The libvlc_picture_t owns the returned buffer, which must not be modified nor
* freed.
*
* \param pic A picture object
* \param size A pointer to a size_t that will hold the size of the buffer [required]
* \return A pointer to the internal buffer.
*/
LIBVLC_API const unsigned char*
libvlc_picture_get_buffer( const libvlc_picture_t* pic, size_t *size );
/**
* Returns the picture type
*
* \param pic A picture object
* \see libvlc_picture_type_t
*/
LIBVLC_API libvlc_picture_type_t
libvlc_picture_type( const libvlc_picture_t* pic );
/**
* Returns the image stride, ie. the number of bytes per line.
* This can only be called on images of type libvlc_picture_Argb
*
* \param pic A picture object
*/
LIBVLC_API unsigned int
libvlc_picture_get_stride( const libvlc_picture_t* pic );
/**
* Returns the width of the image in pixels
*
* \param pic A picture object
*/
LIBVLC_API unsigned int
libvlc_picture_get_width( const libvlc_picture_t* pic );
/**
* Returns the height of the image in pixels
*
* \param pic A picture object
*/
LIBVLC_API unsigned int
libvlc_picture_get_height( const libvlc_picture_t* pic );
/**
* Returns the time at which this picture was generated, in milliseconds
* \param pic A picture object
*/
LIBVLC_API libvlc_time_t
libvlc_picture_get_time( const libvlc_picture_t* pic );
/**
* Returns the number of pictures in the list
*/
LIBVLC_API size_t libvlc_picture_list_count( const libvlc_picture_list_t* list );
/**
* Returns the picture at the provided index.
*
* If the index is out of bound, the result is undefined.
*/
LIBVLC_API libvlc_picture_t* libvlc_picture_list_at( const libvlc_picture_list_t* list,
size_t index );
/**
* Destroys a picture list and releases the pictures it contains
* \param list The list to destroy
*
* Calling this function with a NULL list is safe and will return immediately
*/
LIBVLC_API void libvlc_picture_list_destroy( libvlc_picture_list_t* list );
# ifdef __cplusplus
}
# endif
#endif // VLC_LIBVLC_PICTURE_H

View file

@ -0,0 +1,255 @@
/*****************************************************************************
* libvlc_renderer_discoverer.h: libvlc external API
*****************************************************************************
* Copyright © 2016 VLC authors and VideoLAN
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_LIBVLC_RENDERER_DISCOVERER_H
#define VLC_LIBVLC_RENDERER_DISCOVERER_H 1
# ifdef __cplusplus
extern "C" {
# endif
/**
* @defgroup libvlc_renderer_discoverer LibVLC renderer discoverer
* @ingroup libvlc
* LibVLC renderer discoverer finds available renderers available on the local
* network
* @{
* @file
* LibVLC renderer discoverer external API
*/
typedef struct libvlc_renderer_discoverer_t libvlc_renderer_discoverer_t;
/**
* Renderer discoverer description
*
* \see libvlc_renderer_discoverer_list_get()
*/
typedef struct libvlc_rd_description_t
{
char *psz_name;
char *psz_longname;
} libvlc_rd_description_t;
/** The renderer can render audio */
#define LIBVLC_RENDERER_CAN_AUDIO 0x0001
/** The renderer can render video */
#define LIBVLC_RENDERER_CAN_VIDEO 0x0002
/**
* Renderer item
*
* This struct is passed by a @ref libvlc_event_t when a new renderer is added
* or deleted.
*
* An item is valid until the @ref libvlc_RendererDiscovererItemDeleted event
* is called with the same pointer.
*
* \see libvlc_renderer_discoverer_event_manager()
*/
typedef struct libvlc_renderer_item_t libvlc_renderer_item_t;
/**
* Hold a renderer item, i.e. creates a new reference
*
* This functions need to called from the libvlc_RendererDiscovererItemAdded
* callback if the libvlc user wants to use this item after. (for display or
* for passing it to the mediaplayer for example).
*
* \version LibVLC 3.0.0 or later
*
* \return the current item
*/
LIBVLC_API libvlc_renderer_item_t *
libvlc_renderer_item_hold(libvlc_renderer_item_t *p_item);
/**
* Releases a renderer item, i.e. decrements its reference counter
*
* \version LibVLC 3.0.0 or later
*/
LIBVLC_API void
libvlc_renderer_item_release(libvlc_renderer_item_t *p_item);
/**
* Get the human readable name of a renderer item
*
* \version LibVLC 3.0.0 or later
*
* \return the name of the item (can't be NULL, must *not* be freed)
*/
LIBVLC_API const char *
libvlc_renderer_item_name(const libvlc_renderer_item_t *p_item);
/**
* Get the type (not translated) of a renderer item. For now, the type can only
* be "chromecast" ("upnp", "airplay" may come later).
*
* \version LibVLC 3.0.0 or later
*
* \return the type of the item (can't be NULL, must *not* be freed)
*/
LIBVLC_API const char *
libvlc_renderer_item_type(const libvlc_renderer_item_t *p_item);
/**
* Get the icon uri of a renderer item
*
* \version LibVLC 3.0.0 or later
*
* \return the uri of the item's icon (can be NULL, must *not* be freed)
*/
LIBVLC_API const char *
libvlc_renderer_item_icon_uri(const libvlc_renderer_item_t *p_item);
/**
* Get the flags of a renderer item
*
* \see LIBVLC_RENDERER_CAN_AUDIO
* \see LIBVLC_RENDERER_CAN_VIDEO
*
* \version LibVLC 3.0.0 or later
*
* \return bitwise flag: capabilities of the renderer, see
*/
LIBVLC_API int
libvlc_renderer_item_flags(const libvlc_renderer_item_t *p_item);
/**
* Create a renderer discoverer object by name
*
* After this object is created, you should attach to events in order to be
* notified of the discoverer events.
*
* You need to call libvlc_renderer_discoverer_start() in order to start the
* discovery.
*
* \see libvlc_renderer_discoverer_event_manager()
* \see libvlc_renderer_discoverer_start()
*
* \version LibVLC 3.0.0 or later
*
* \param p_inst libvlc instance
* \param psz_name service name; use libvlc_renderer_discoverer_list_get() to
* get a list of the discoverer names available in this libVLC instance
* \return media discover object or NULL in case of error
*/
LIBVLC_API libvlc_renderer_discoverer_t *
libvlc_renderer_discoverer_new( libvlc_instance_t *p_inst,
const char *psz_name );
/**
* Release a renderer discoverer object
*
* \version LibVLC 3.0.0 or later
*
* \param p_rd renderer discoverer object
*/
LIBVLC_API void
libvlc_renderer_discoverer_release( libvlc_renderer_discoverer_t *p_rd );
/**
* Start renderer discovery
*
* To stop it, call libvlc_renderer_discoverer_stop() or
* libvlc_renderer_discoverer_release() directly.
*
* \see libvlc_renderer_discoverer_stop()
*
* \version LibVLC 3.0.0 or later
*
* \param p_rd renderer discoverer object
* \return -1 in case of error, 0 otherwise
*/
LIBVLC_API int
libvlc_renderer_discoverer_start( libvlc_renderer_discoverer_t *p_rd );
/**
* Stop renderer discovery.
*
* \see libvlc_renderer_discoverer_start()
*
* \version LibVLC 3.0.0 or later
*
* \param p_rd renderer discoverer object
*/
LIBVLC_API void
libvlc_renderer_discoverer_stop( libvlc_renderer_discoverer_t *p_rd );
/**
* Get the event manager of the renderer discoverer
*
* The possible events to attach are @ref libvlc_RendererDiscovererItemAdded
* and @ref libvlc_RendererDiscovererItemDeleted.
*
* The @ref libvlc_renderer_item_t struct passed to event callbacks is owned by
* VLC, users should take care of holding/releasing this struct for their
* internal usage.
*
* \see libvlc_event_t.u.renderer_discoverer_item_added.item
* \see libvlc_event_t.u.renderer_discoverer_item_removed.item
*
* \version LibVLC 3.0.0 or later
*
* \return a valid event manager (can't fail)
*/
LIBVLC_API libvlc_event_manager_t *
libvlc_renderer_discoverer_event_manager( libvlc_renderer_discoverer_t *p_rd );
/**
* Get media discoverer services
*
* \see libvlc_renderer_list_release()
*
* \version LibVLC 3.0.0 and later
*
* \param p_inst libvlc instance
* \param ppp_services address to store an allocated array of renderer
* discoverer services (must be freed with libvlc_renderer_list_release() by
* the caller) [OUT]
*
* \return the number of media discoverer services (0 on error)
*/
LIBVLC_API size_t
libvlc_renderer_discoverer_list_get( libvlc_instance_t *p_inst,
libvlc_rd_description_t ***ppp_services );
/**
* Release an array of media discoverer services
*
* \see libvlc_renderer_discoverer_list_get()
*
* \version LibVLC 3.0.0 and later
*
* \param pp_services array to release
* \param i_count number of elements in the array
*/
LIBVLC_API void
libvlc_renderer_discoverer_list_release( libvlc_rd_description_t **pp_services,
size_t i_count );
/** @} */
# ifdef __cplusplus
}
# endif
#endif

79
Libs/vlc/libvlc_version.h Normal file
View file

@ -0,0 +1,79 @@
/*****************************************************************************
* libvlc_version.h
*****************************************************************************
* Copyright (C) 2010 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/**
* \file
* This file defines version macros for LibVLC.
* Those macros are primilarly intended for conditional (pre)compilation.
* To get the run-time LibVLC version, use libvlc_get_version() instead
* (the run-time version may be more recent than build-time one, thanks to
* backward binary compatibility).
*
* \version This header file is available in LibVLC 1.1.4 and higher.
*/
#ifndef LIBVLC_VERSION_H
# define LIBVLC_VERSION_H 1
/** LibVLC major version number */
# define LIBVLC_VERSION_MAJOR (4)
/** LibVLC minor version number */
# define LIBVLC_VERSION_MINOR (0)
/** LibVLC revision */
# define LIBVLC_VERSION_REVISION (0)
# define LIBVLC_VERSION_EXTRA (0)
/** Makes a single integer from a LibVLC version numbers */
# define LIBVLC_VERSION(maj,min,rev,extra) \
((maj << 24) | (min << 16) | (rev << 8) | (extra))
/** LibVLC full version as a single integer (for comparison) */
# define LIBVLC_VERSION_INT \
LIBVLC_VERSION(LIBVLC_VERSION_MAJOR, LIBVLC_VERSION_MINOR, \
LIBVLC_VERSION_REVISION, LIBVLC_VERSION_EXTRA)
/** LibVLC ABI major version number, updated when incompatible changes are added */
# define LIBVLC_ABI_VERSION_MAJOR (12)
/** LibVLC ABI minor version number, updated when compatible changes are added */
# define LIBVLC_ABI_VERSION_MINOR (0)
/** LibVLC ABI micro version number, updated with new releases */
# define LIBVLC_ABI_VERSION_MICRO (0)
/** LibVLC full ABI version combining the major VLC version and the .so version:
* - A 0xFF000000 mask gives the VLC major version,
* - A 0x00FF0000 mask gives the LibVLC major ABI version,
* - A 0x0000FF00 mask gives the LibVLC minor ABI version,
* - A 0x000000FF mask gives the LibVLC ABI revision.
*
* LibVLC is considered compatible with your code if the VLC major and LibVLC
* major values are equal and the minor ABI version is equal or higher than the
* value you compiled with.
*/
# define LIBVLC_ABI_VERSION_INT \
LIBVLC_VERSION(LIBVLC_VERSION_MAJOR, LIBVLC_ABI_VERSION_MAJOR, \
LIBVLC_ABI_VERSION_MINOR, LIBVLC_ABI_VERSION_MICRO )
#endif

67
Libs/vlc/libvlc_video.h Normal file
View file

@ -0,0 +1,67 @@
/*****************************************************************************
* libvlc_video.h: libvlc video-related enumerations
*****************************************************************************
* Copyright (C) 1998-2010 VLC authors and VideoLAN
* Copyright (C) 2023 Videolabs
*
* Authors: Filippo Carone <littlejohn@videolan.org>
* Pierre d'Herbemont <pdherbemont@videolan.org>
* Alexandre Janniaux <ajanni@videolabs.io>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_LIBVLC_VIDEO_H
#define VLC_LIBVLC_VIDEO_H 1
# ifdef __cplusplus
extern "C"{
# endif
typedef enum libvlc_video_orient_t
{
libvlc_video_orient_top_left, /**< Normal. Top line represents top, left column left. */
libvlc_video_orient_top_right, /**< Flipped horizontally */
libvlc_video_orient_bottom_left, /**< Flipped vertically */
libvlc_video_orient_bottom_right, /**< Rotated 180 degrees */
libvlc_video_orient_left_top, /**< Transposed */
libvlc_video_orient_left_bottom, /**< Rotated 90 degrees clockwise (or 270 anti-clockwise) */
libvlc_video_orient_right_top, /**< Rotated 90 degrees anti-clockwise */
libvlc_video_orient_right_bottom /**< Anti-transposed */
} libvlc_video_orient_t;
typedef enum libvlc_video_projection_t
{
libvlc_video_projection_rectangular,
libvlc_video_projection_equirectangular, /**< 360 spherical */
libvlc_video_projection_cubemap_layout_standard = 0x100,
} libvlc_video_projection_t;
typedef enum libvlc_video_multiview_t
{
libvlc_video_multiview_2d, /**< No stereoscopy: 2D picture. */
libvlc_video_multiview_stereo_sbs, /**< Side-by-side */
libvlc_video_multiview_stereo_tb, /**< Top-bottom */
libvlc_video_multiview_stereo_row, /**< Row sequential */
libvlc_video_multiview_stereo_col, /**< Column sequential */
libvlc_video_multiview_stereo_frame, /**< Frame sequential */
libvlc_video_multiview_stereo_checkerboard, /**< Checkerboard pattern */
} libvlc_video_multiview_t;
# ifdef __cplusplus
} // extern "C"
# endif
#endif

55
Libs/vlc/vlc.h Normal file
View file

@ -0,0 +1,55 @@
/*****************************************************************************
* vlc.h: global header for libvlc
*****************************************************************************
* Copyright (C) 1998-2008 VLC authors and VideoLAN
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Gildas Bazin <gbazin@netcourrier.com>
* Derk-Jan Hartman <hartman at videolan dot org>
* Pierre d'Herbemont <pdherbemont@videolan.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_VLC_H
#define VLC_VLC_H 1
/**
* \file
* This file defines libvlc new external API
*/
# ifdef __cplusplus
extern "C" {
# endif
#include "libvlc.h"
#include "libvlc_renderer_discoverer.h"
#include "libvlc_picture.h"
#include "libvlc_media.h"
#include "libvlc_media_player.h"
#include "libvlc_media_list.h"
#include "libvlc_media_list_player.h"
#include "libvlc_media_discoverer.h"
#include "libvlc_events.h"
#include "libvlc_dialog.h"
#include "libvlc_version.h"
# ifdef __cplusplus
}
# endif
#endif /* _VLC_VLC_H */

BIN
Libs/vlc/x64/libvlc.dll Normal file

Binary file not shown.

BIN
Libs/vlc/x64/libvlc.lib Normal file

Binary file not shown.

BIN
Libs/vlc/x64/libvlccore.dll Normal file

Binary file not shown.

BIN
Libs/vlc/x64/libvlccore.lib Normal file

Binary file not shown.

BIN
Libs/vlc/x86/libvlc.dll Normal file

Binary file not shown.

BIN
Libs/vlc/x86/libvlc.lib Normal file

Binary file not shown.

BIN
Libs/vlc/x86/libvlccore.dll Normal file

Binary file not shown.

BIN
Libs/vlc/x86/libvlccore.lib Normal file

Binary file not shown.

View file

@ -6,6 +6,11 @@
Flow.SetIntroImagePath("Screens\\main.jpg") Flow.SetIntroImagePath("Screens\\main.jpg")
-- Intro video plays right after or instead of intro image, if specified.
-- If you don't want it to appear, just remove this line.
--Flow.SetIntroVideoPath("FMV\\core.mp4")
-- Set overall amount of secrets in game. -- Set overall amount of secrets in game.
-- If set to 0, secrets won't be displayed in statistics. -- If set to 0, secrets won't be displayed in statistics.

View file

@ -39,6 +39,7 @@
#include "Math/Math.h" #include "Math/Math.h"
#include "Objects/Effects/LensFlare.h" #include "Objects/Effects/LensFlare.h"
#include "Objects/Effects/tr4_locusts.h" #include "Objects/Effects/tr4_locusts.h"
#include "Objects/Effects/Fireflies.h"
#include "Objects/Generic/Object/objects.h" #include "Objects/Generic/Object/objects.h"
#include "Objects/Generic/Object/rope.h" #include "Objects/Generic/Object/rope.h"
#include "Objects/Generic/Switches/generic_switch.h" #include "Objects/Generic/Switches/generic_switch.h"
@ -59,7 +60,7 @@
#include "Specific/Input/Input.h" #include "Specific/Input/Input.h"
#include "Specific/level.h" #include "Specific/level.h"
#include "Specific/winmain.h" #include "Specific/winmain.h"
#include "Objects/Effects/Fireflies.h" #include "Specific/Video/Video.h"
using namespace std::chrono; using namespace std::chrono;
using namespace TEN::Effects; using namespace TEN::Effects;
@ -91,6 +92,7 @@ using namespace TEN::Renderer;
using namespace TEN::Entities::Creatures::TR3; using namespace TEN::Entities::Creatures::TR3;
using namespace TEN::Entities::Effects; using namespace TEN::Entities::Effects;
using namespace TEN::Effects::Fireflies; using namespace TEN::Effects::Fireflies;
using namespace TEN::Video;
constexpr auto DEATH_NO_INPUT_TIMEOUT = 10 * FPS; constexpr auto DEATH_NO_INPUT_TIMEOUT = 10 * FPS;
constexpr auto DEATH_INPUT_TIMEOUT = 3 * FPS; constexpr auto DEATH_INPUT_TIMEOUT = 3 * FPS;
@ -356,18 +358,21 @@ unsigned CALLBACK GameMain(void *)
TimeInit(); TimeInit();
// Do fixed-time title image. // Do fixed-time title image.
if (g_GameFlow->IntroImagePath.empty()) if (!g_GameFlow->IntroImagePath.empty())
{
TENLog("Intro image path not set.", LogLevel::Warning);
}
else
{
g_Renderer.RenderTitleImage(); g_Renderer.RenderTitleImage();
// Play intro video.
if (!g_GameFlow->IntroVideoPath.empty())
{
g_VideoPlayer.Play(g_GameFlow->IntroVideoPath);
while (DoTheGame && g_VideoPlayer.Update());
} }
// Execute Lua gameflow and play game. // Execute Lua gameflow and play game.
g_GameFlow->DoFlow(); g_GameFlow->DoFlow();
// Exit game.
DeInitialize();
DoTheGame = false; DoTheGame = false;
// Finish thread. // Finish thread.
@ -490,6 +495,25 @@ int GetRandomDraw()
return Random::GenerateInt(); return Random::GenerateInt();
} }
void DeInitialize()
{
g_VideoPlayer.DeInitialize();
Sound_DeInit();
DeinitializeInput();
delete g_GameScript;
g_GameScript = nullptr;
delete g_GameFlow;
g_GameFlow = nullptr;
delete g_GameScriptEntities;
g_GameScriptEntities = nullptr;
delete g_GameStringsHandler;
g_GameStringsHandler = nullptr;
}
void CleanUp() void CleanUp()
{ {
// Reset oscillator seed. // Reset oscillator seed.
@ -586,6 +610,7 @@ void InitializeScripting(int levelIndex, bool loadGame)
void DeInitializeScripting(int levelIndex, GameStatus reason) void DeInitializeScripting(int levelIndex, GameStatus reason)
{ {
// Reload gameflow script to clear level script variables. // Reload gameflow script to clear level script variables.
if (reason != GameStatus::ExitGame)
g_GameFlow->LoadFlowScript(); g_GameFlow->LoadFlowScript();
g_GameScript->FreeLevelScripts(); g_GameScript->FreeLevelScripts();
@ -658,6 +683,9 @@ GameStatus DoGameLoop(int levelIndex)
{ {
g_Synchronizer.Sync(); g_Synchronizer.Sync();
if (g_VideoPlayer.Update())
continue;
while (g_Synchronizer.Synced()) while (g_Synchronizer.Synced())
{ {
status = ControlPhase(false); status = ControlPhase(false);
@ -686,7 +714,7 @@ GameStatus DoGameLoop(int levelIndex)
} }
} }
EndGameLoop(levelIndex, status); EndGameLoop(levelIndex, DoTheGame ? status : GameStatus::ExitGame);
return status; return status;
} }
@ -696,9 +724,12 @@ void EndGameLoop(int levelIndex, GameStatus reason)
// Save last screenshot for loading screen. // Save last screenshot for loading screen.
g_Renderer.DumpGameScene(); g_Renderer.DumpGameScene();
if (reason == GameStatus::LevelComplete)
SaveGame::SaveHub(levelIndex); SaveGame::SaveHub(levelIndex);
DeInitializeScripting(levelIndex, reason); DeInitializeScripting(levelIndex, reason);
g_VideoPlayer.Stop();
StopAllSounds(); StopAllSounds();
StopSoundTracks(SOUND_XFADETIME_LEVELJUMP, true); StopSoundTracks(SOUND_XFADETIME_LEVELJUMP, true);
StopRumble(); StopRumble();
@ -721,7 +752,7 @@ void HandleControls(bool isTitle)
{ {
// Poll input devices and update input variables. // Poll input devices and update input variables.
// TODO: To allow cutscene skipping later, don't clear Deselect action. // TODO: To allow cutscene skipping later, don't clear Deselect action.
UpdateInputActions(LaraItem, true); UpdateInputActions(false, true);
if (isTitle) if (isTitle)
ClearAction(In::Look); ClearAction(In::Look);

View file

@ -96,6 +96,7 @@ void KillMoveEffects();
void UpdateShatters(); void UpdateShatters();
void CleanUp(); void CleanUp();
void DeInitialize();
void InitializeOrLoadGame(bool loadGame); void InitializeOrLoadGame(bool loadGame);
void InitializeScripting(int levelIndex, bool loadGame); void InitializeScripting(int levelIndex, bool loadGame);

View file

@ -51,6 +51,10 @@ namespace TEN::Debug
} }
auto logger = spdlog::get("multi_sink"); auto logger = spdlog::get("multi_sink");
if (!logger)
return;
switch (level) switch (level)
{ {
case LogLevel::Error: case LogLevel::Error:

View file

@ -27,12 +27,14 @@
#include "Specific/configuration.h" #include "Specific/configuration.h"
#include "Specific/level.h" #include "Specific/level.h"
#include "Specific/trutils.h" #include "Specific/trutils.h"
#include "Specific/Video/Video.h"
#include "Specific/winmain.h" #include "Specific/winmain.h"
using namespace TEN::Effects::DisplaySprite; using namespace TEN::Effects::DisplaySprite;
using namespace TEN::Input; using namespace TEN::Input;
using namespace TEN::Renderer; using namespace TEN::Renderer;
using namespace TEN::Utils; using namespace TEN::Utils;
using namespace TEN::Video;
namespace TEN::Gui namespace TEN::Gui
{ {
@ -716,7 +718,7 @@ namespace TEN::Gui
else else
{ {
g_Renderer.PrepareScene(); // Just for updating blink time. g_Renderer.PrepareScene(); // Just for updating blink time.
UpdateInputActions(item); UpdateInputActions();
} }
if (CurrentSettings.IgnoreInput) if (CurrentSettings.IgnoreInput)
@ -1157,7 +1159,7 @@ namespace TEN::Gui
static const int numOptionsOptions = 2; static const int numOptionsOptions = 2;
TimeInMenu++; TimeInMenu++;
UpdateInputActions(item); UpdateInputActions();
switch (MenuToDisplay) switch (MenuToDisplay)
{ {
@ -3185,6 +3187,7 @@ namespace TEN::Gui
bool GuiController::CallPause() bool GuiController::CallPause()
{ {
g_Renderer.DumpGameScene(SceneRenderMode::NoHud); g_Renderer.DumpGameScene(SceneRenderMode::NoHud);
g_VideoPlayer.Pause();
PauseAllSounds(SoundPauseMode::Pause); PauseAllSounds(SoundPauseMode::Pause);
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
@ -3249,6 +3252,7 @@ namespace TEN::Gui
} }
else else
{ {
g_VideoPlayer.Resume();
ResumeAllSounds(SoundPauseMode::Pause); ResumeAllSounds(SoundPauseMode::Pause);
} }
@ -3266,6 +3270,7 @@ namespace TEN::Gui
player.Inventory.OldBusy = player.Inventory.IsBusy; player.Inventory.OldBusy = player.Inventory.IsBusy;
g_Renderer.DumpGameScene(SceneRenderMode::NoHud); g_Renderer.DumpGameScene(SceneRenderMode::NoHud);
g_VideoPlayer.Pause();
PauseAllSounds(SoundPauseMode::Inventory); PauseAllSounds(SoundPauseMode::Inventory);
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
@ -3296,7 +3301,7 @@ namespace TEN::Gui
SaveGame::Statistics.Game.TimeTaken++; SaveGame::Statistics.Game.TimeTaken++;
SaveGame::Statistics.Level.TimeTaken++; SaveGame::Statistics.Level.TimeTaken++;
UpdateInputActions(item); UpdateInputActions();
if (GuiIsDeselected() || IsClicked(In::Inventory)) if (GuiIsDeselected() || IsClicked(In::Inventory))
{ {
@ -3387,6 +3392,7 @@ namespace TEN::Gui
AlterFOV(LastFOV); AlterFOV(LastFOV);
g_Renderer.PrepareScene(); g_Renderer.PrepareScene();
g_VideoPlayer.Resume();
ResumeAllSounds(SoundPauseMode::Inventory); ResumeAllSounds(SoundPauseMode::Inventory);
player.Inventory.IsBusy = player.Inventory.OldBusy; player.Inventory.IsBusy = player.Inventory.OldBusy;

View file

@ -40,6 +40,7 @@
#include "Specific/clock.h" #include "Specific/clock.h"
#include "Specific/level.h" #include "Specific/level.h"
#include "Specific/savegame/flatbuffers/ten_savegame_generated.h" #include "Specific/savegame/flatbuffers/ten_savegame_generated.h"
#include "Specific/Video/Video.h"
using namespace flatbuffers; using namespace flatbuffers;
using namespace TEN::Collision::Floordata; using namespace TEN::Collision::Floordata;
@ -53,6 +54,7 @@ using namespace TEN::Entities::Switches;
using namespace TEN::Entities::TR4; using namespace TEN::Entities::TR4;
using namespace TEN::Gui; using namespace TEN::Gui;
using namespace TEN::Renderer; using namespace TEN::Renderer;
using namespace TEN::Video;
namespace Save = TEN::Save; namespace Save = TEN::Save;
@ -293,6 +295,15 @@ const std::vector<byte> SaveGame::Build()
sgGameStatisticsBuilder.add_timer(SaveGame::Statistics.Game.TimeTaken); sgGameStatisticsBuilder.add_timer(SaveGame::Statistics.Game.TimeTaken);
auto gameStatisticsOffset = sgGameStatisticsBuilder.Finish(); auto gameStatisticsOffset = sgGameStatisticsBuilder.Finish();
// Background video playback
auto videoNameOffset = fbb.CreateString(g_VideoPlayer.GetFileName());
Save::VideoInfoBuilder sgVideoInfoBuilder{ fbb };
sgVideoInfoBuilder.add_name(videoNameOffset);
sgVideoInfoBuilder.add_position(g_VideoPlayer.GetNormalizedPosition());
sgVideoInfoBuilder.add_silent(g_VideoPlayer.GetSilent());
sgVideoInfoBuilder.add_looped(g_VideoPlayer.GetLooped());
auto videoInfoOffset = sgVideoInfoBuilder.Finish();
// Lara // Lara
std::vector<int> puzzles; std::vector<int> puzzles;
for (int i = 0; i < NUM_PUZZLES; i++) for (int i = 0; i < NUM_PUZZLES; i++)
@ -950,7 +961,7 @@ const std::vector<byte> SaveGame::Build()
fireflySave.add_b(firefly.b); fireflySave.add_b(firefly.b);
fireflySave.add_on(firefly.on); fireflySave.add_on(firefly.on);
fireflySave.add_size(firefly.size); fireflySave.add_size(firefly.size);
fireflySave.add_rot_Ang(firefly.rotAng); fireflySave.add_rot_ang(firefly.rotAng);
auto fireflySaveOffset = fireflySave.Finish(); auto fireflySaveOffset = fireflySave.Finish();
fireflySwarm.push_back(fireflySaveOffset); fireflySwarm.push_back(fireflySaveOffset);
@ -1587,8 +1598,8 @@ const std::vector<byte> SaveGame::Build()
sgb.add_postprocess_strength(g_Renderer.GetPostProcessStrength()); sgb.add_postprocess_strength(g_Renderer.GetPostProcessStrength());
sgb.add_postprocess_tint(&FromVector3(g_Renderer.GetPostProcessTint())); sgb.add_postprocess_tint(&FromVector3(g_Renderer.GetPostProcessTint()));
sgb.add_soundtracks(soundtrackOffset); sgb.add_soundtracks(soundtrackOffset);
sgb.add_cd_flags(soundtrackMapOffset); sgb.add_cd_flags(soundtrackMapOffset);
sgb.add_video(videoInfoOffset);
sgb.add_action_queue(actionQueueOffset); sgb.add_action_queue(actionQueueOffset);
sgb.add_flip_maps(flipMapsOffset); sgb.add_flip_maps(flipMapsOffset);
sgb.add_flip_stats(flipStatsOffset); sgb.add_flip_stats(flipStatsOffset);
@ -2302,6 +2313,14 @@ static void ParseEffects(const Save::SaveGame* s)
PlaySoundTrack(track->name()->str(), (SoundTrackType)i, track->position(), SOUND_XFADETIME_LEVELJUMP); PlaySoundTrack(track->name()->str(), (SoundTrackType)i, track->position(), SOUND_XFADETIME_LEVELJUMP);
} }
// Restore video playback.
std::string videoName = s->video()->name()->str();
if (!videoName.empty())
{
g_VideoPlayer.Play(videoName, VideoPlaybackMode::Background, s->video()->silent(), s->video()->looped());
g_VideoPlayer.SetNormalizedPosition(s->video()->position());
}
// Load fish swarm. // Load fish swarm.
for (int i = 0; i < s->fish_swarm()->size(); i++) for (int i = 0; i < s->fish_swarm()->size(); i++)
{ {
@ -2351,7 +2370,7 @@ static void ParseEffects(const Save::SaveGame* s)
firefly.b = fireflySave->b(); firefly.b = fireflySave->b();
firefly.on = fireflySave->on(); firefly.on = fireflySave->on();
firefly.size = fireflySave->size(); firefly.size = fireflySave->size();
firefly.rotAng = fireflySave->rot_Ang(); firefly.rotAng = fireflySave->rot_ang();
FireflySwarm.push_back(firefly); FireflySwarm.push_back(firefly);
} }

View file

@ -23,6 +23,6 @@ namespace TEN::Renderer::ConstantBuffers
uint32_t NumFrames; uint32_t NumFrames;
uint32_t Fps; uint32_t Fps;
uint32_t Type; uint32_t Type;
uint32_t padding; uint32_t Padding;
}; };
} }

View file

@ -6,11 +6,11 @@
#include "Renderer/Structures/RendererRectangle.h" #include "Renderer/Structures/RendererRectangle.h"
#include "Renderer/RenderView.h" #include "Renderer/RenderView.h"
#include "Renderer/RendererUtils.h" #include "Renderer/RendererUtils.h"
#include "Renderer/Graphics/RenderTargetCube.h"
#include "Renderer/Graphics/VertexBuffer.h" #include "Renderer/Graphics/VertexBuffer.h"
#include "Renderer/Structures/RendererHudBar.h" #include "Renderer/Structures/RendererHudBar.h"
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Specific/clock.h" #include "Specific/clock.h"
#include "Graphics/RenderTargetCube.h"
namespace TEN::Renderer namespace TEN::Renderer
{ {
@ -62,6 +62,18 @@ namespace TEN::Renderer
_isLocked = true; _isLocked = true;
} }
void Renderer::UpdateVideoTexture(Texture2D* texture)
{
_videoSprite.X = _videoSprite.Y = 0;
_videoSprite.Width = texture->Width;
_videoSprite.Height = texture->Height;
_videoSprite.UV[0] = Vector2(0,0);
_videoSprite.UV[1] = Vector2(1,0);
_videoSprite.UV[2] = Vector2(1,1);
_videoSprite.UV[3] = Vector2(0,1);
_videoSprite.Texture = texture;
}
void Renderer::ReloadShaders(bool recompileAAShaders) void Renderer::ReloadShaders(bool recompileAAShaders)
{ {
try try

View file

@ -231,6 +231,7 @@ namespace TEN::Renderer
std::vector<TexturePair> _moveablesTextures; std::vector<TexturePair> _moveablesTextures;
std::vector<TexturePair> _staticTextures; std::vector<TexturePair> _staticTextures;
std::vector<Texture2D> _spritesTextures; std::vector<Texture2D> _spritesTextures;
RendererSprite _videoSprite; // Video texture is an unique case
Matrix _playerWorldMatrix; Matrix _playerWorldMatrix;
@ -451,7 +452,7 @@ namespace TEN::Renderer
void PrepareShockwaves(RenderView& view); void PrepareShockwaves(RenderView& view);
void PrepareRipples(RenderView& view); void PrepareRipples(RenderView& view);
void PrepareUnderwaterBloodParticles(RenderView& view); void PrepareUnderwaterBloodParticles(RenderView& view);
void DrawFullScreenQuad(ID3D11ShaderResourceView* texture, Vector3 color, bool fit = true); void DrawFullScreenQuad(ID3D11ShaderResourceView* texture, Vector3 color, bool fit = true, float customAspect = 0.0f);
void DrawFullScreenSprite(RendererSprite* sprite, DirectX::SimpleMath::Vector3 color, bool fit = true); void DrawFullScreenSprite(RendererSprite* sprite, DirectX::SimpleMath::Vector3 color, bool fit = true);
void PrepareSmokeParticles(RenderView& view); void PrepareSmokeParticles(RenderView& view);
void PrepareSparkParticles(RenderView& view); void PrepareSparkParticles(RenderView& view);
@ -609,7 +610,7 @@ namespace TEN::Renderer
RendererMesh* GetRendererMeshFromTrMesh(RendererObject* obj, MESH* meshPtr, short boneIndex, int isJoints, int isHairs, int* lastVertex, int* lastIndex); RendererMesh* GetRendererMeshFromTrMesh(RendererObject* obj, MESH* meshPtr, short boneIndex, int isJoints, int isHairs, int* lastVertex, int* lastIndex);
void DrawBar(float percent, const RendererHudBar& bar, GAME_OBJECT_ID textureSlot, int frame, bool poison); void DrawBar(float percent, const RendererHudBar& bar, GAME_OBJECT_ID textureSlot, int frame, bool poison);
void Create(); void Create();
void Initialize(int w, int h, bool windowed, HWND handle); void Initialize(const std::string& gameDir, int w, int h, bool windowed, HWND handle);
void ReloadShaders(bool recompileAAShaders = false); void ReloadShaders(bool recompileAAShaders = false);
void Render(float interpFactor); void Render(float interpFactor);
void RenderTitle(float interpFactor); void RenderTitle(float interpFactor);
@ -633,6 +634,8 @@ namespace TEN::Renderer
void AddDynamicSpotLight(const Vector3& pos, const Vector3& dir, float radius, float falloff, float distance, const Color& color, bool castShadows, int hash = 0); void AddDynamicSpotLight(const Vector3& pos, const Vector3& dir, float radius, float falloff, float distance, const Color& color, bool castShadows, int hash = 0);
void RenderLoadingScreen(float percentage); void RenderLoadingScreen(float percentage);
void RenderFreezeMode(float interpFactor, bool staticBackground); void RenderFreezeMode(float interpFactor, bool staticBackground);
void RenderFullScreenTexture(ID3D11ShaderResourceView* texture, float aspect);
void UpdateVideoTexture(Texture2D* texture);
void UpdateProgress(float value); void UpdateProgress(float value);
void ToggleFullScreen(bool force = false); void ToggleFullScreen(bool force = false);
void SetFullScreen(); void SetFullScreen();

View file

@ -68,11 +68,18 @@ namespace TEN::Renderer
_animatedTextures[i] = tex; _animatedTextures[i] = tex;
} }
std::transform(g_Level.AnimatedTexturesSequences.begin(), g_Level.AnimatedTexturesSequences.end(), std::back_inserter(_animatedTextureSets), [](ANIMATED_TEXTURES_SEQUENCE& sequence) { std::transform(g_Level.AnimatedTexturesSequences.begin(), g_Level.AnimatedTexturesSequences.end(), std::back_inserter(_animatedTextureSets), [](ANIMATED_TEXTURES_SEQUENCE& sequence)
{
RendererAnimatedTextureSet set{}; RendererAnimatedTextureSet set{};
set.NumTextures = sequence.numFrames;
std::transform(sequence.frames.begin(), sequence.frames.end(), std::back_inserter(set.Textures), [](ANIMATED_TEXTURES_FRAME& frm) { set.NumTextures = sequence.NumFrames;
set.Type = (AnimatedTextureType)sequence.Type;
set.Fps = sequence.Fps;
std::transform(sequence.Frames.begin(), sequence.Frames.end(), std::back_inserter(set.Textures), [](ANIMATED_TEXTURES_FRAME& frm)
{
RendererAnimatedTexture tex{}; RendererAnimatedTexture tex{};
tex.UV[0].x = frm.x1; tex.UV[0].x = frm.x1;
tex.UV[0].y = frm.y1; tex.UV[0].y = frm.y1;
tex.UV[1].x = frm.x2; tex.UV[1].x = frm.x2;
@ -81,9 +88,21 @@ namespace TEN::Renderer
tex.UV[2].y = frm.y3; tex.UV[2].y = frm.y3;
tex.UV[3].x = frm.x4; tex.UV[3].x = frm.x4;
tex.UV[3].y = frm.y4; tex.UV[3].y = frm.y4;
float UMin = std::min({ tex.UV[0].x, tex.UV[1].x, tex.UV[2].x, tex.UV[3].x });
float VMin = std::min({ tex.UV[0].y, tex.UV[1].y, tex.UV[2].y, tex.UV[3].y });
float UMax = std::max({ tex.UV[0].x, tex.UV[1].x, tex.UV[2].x, tex.UV[3].x });
float VMax = std::max({ tex.UV[0].y, tex.UV[1].y, tex.UV[2].y, tex.UV[3].y });
for (int i = 0; i < 4; ++i)
{
tex.NormalizedUV[i].x = (tex.UV[i].x - UMin) / (UMax - UMin);
tex.NormalizedUV[i].y = (tex.UV[i].y - VMin) / (VMax - VMin);
}
return tex; return tex;
}); });
set.Fps = sequence.Fps;
return set; return set;
}); });

View file

@ -2183,6 +2183,33 @@ namespace TEN::Renderer
SetBlendMode(BlendMode::Opaque, true);*/ SetBlendMode(BlendMode::Opaque, true);*/
} }
void Renderer::RenderFullScreenTexture(ID3D11ShaderResourceView* texture, float aspect)
{
if (texture == nullptr)
return;
// Set basic render states.
SetBlendMode(BlendMode::Opaque);
SetCullMode(CullMode::CounterClockwise);
// Clear screen
_context->ClearRenderTargetView(_backBuffer.RenderTargetView.Get(), Colors::Black);
_context->ClearDepthStencilView(_backBuffer.DepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
// Bind back buffer.
_context->OMSetRenderTargets(1, _backBuffer.RenderTargetView.GetAddressOf(), _backBuffer.DepthStencilView.Get());
_context->RSSetViewports(1, &_viewport);
ResetScissor();
// Draw full screen background.
DrawFullScreenQuad(texture, Vector3::One, true, aspect);
ClearScene();
_context->ClearState();
_swapChain->Present(1, 0);
}
void Renderer::DumpGameScene(SceneRenderMode renderMode) void Renderer::DumpGameScene(SceneRenderMode renderMode)
{ {
RenderScene(&_dumpScreenRenderTarget, _gameCamera, renderMode); RenderScene(&_dumpScreenRenderTarget, _gameCamera, renderMode);
@ -2796,16 +2823,32 @@ namespace TEN::Renderer
// Draw geometry. // Draw geometry.
if (animated) if (animated)
{ {
BindTexture(TextureRegister::ColorMap,
&std::get<0>(_animatedTextures[bucket.Texture]),
SamplerStateRegister::AnisotropicClamp);
BindTexture(TextureRegister::NormalMap,
&std::get<1>(_animatedTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
const auto& set = _animatedTextureSets[bucket.Texture]; const auto& set = _animatedTextureSets[bucket.Texture];
_stAnimated.NumFrames = set.NumTextures;
_stAnimated.Type = 0; // Stream video texture, if video playback is active, otherwise show original texture.
if (set.Type == AnimatedTextureType::Video && _videoSprite.Texture && _videoSprite.Texture->Texture)
{
_stAnimated.Type = 0; // Dummy type, should be set to 0 to avoid incorrect UV mapping.
_stAnimated.Fps = 1;
_stAnimated.NumFrames = 1;
BindTexture(TextureRegister::ColorMap, _videoSprite.Texture, SamplerStateRegister::AnisotropicClamp);
BindTexture(TextureRegister::NormalMap, &std::get<1>(_animatedTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
// Use normalized UVs, because we are showing the whole video texture on a single face.
_stAnimated.Textures[0].TopLeft = set.Textures[0].NormalizedUV[0];
_stAnimated.Textures[0].TopRight = set.Textures[0].NormalizedUV[1];
_stAnimated.Textures[0].BottomRight = set.Textures[0].NormalizedUV[2];
_stAnimated.Textures[0].BottomLeft = set.Textures[0].NormalizedUV[3];
}
else
{
_stAnimated.Type = (int)set.Type;
_stAnimated.Fps = set.Fps; _stAnimated.Fps = set.Fps;
_stAnimated.NumFrames = set.NumTextures;
BindTexture(TextureRegister::ColorMap, &std::get<0>(_animatedTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
BindTexture(TextureRegister::NormalMap, &std::get<1>(_animatedTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp);
for (unsigned char j = 0; j < set.NumTextures; j++) for (unsigned char j = 0; j < set.NumTextures; j++)
{ {
@ -2820,6 +2863,8 @@ namespace TEN::Renderer
_stAnimated.Textures[j].BottomRight = set.Textures[j].UV[2]; _stAnimated.Textures[j].BottomRight = set.Textures[j].UV[2];
_stAnimated.Textures[j].BottomLeft = set.Textures[j].UV[3]; _stAnimated.Textures[j].BottomLeft = set.Textures[j].UV[3];
} }
}
_cbAnimated.UpdateData(_stAnimated, _context.Get()); _cbAnimated.UpdateData(_stAnimated, _context.Get());
} }
else else

View file

@ -407,7 +407,7 @@ namespace TEN::Renderer
_primitiveBatch->End(); _primitiveBatch->End();
} }
void Renderer::DrawFullScreenQuad(ID3D11ShaderResourceView* texture, Vector3 color, bool fit) void Renderer::DrawFullScreenQuad(ID3D11ShaderResourceView* texture, Vector3 color, bool fit, float customAspect)
{ {
constexpr auto VERTEX_COUNT = 4; constexpr auto VERTEX_COUNT = 4;
constexpr auto UV_RANGE = std::pair<Vector2, Vector2>(Vector2(0.0f), Vector2(1.0f)); constexpr auto UV_RANGE = std::pair<Vector2, Vector2>(Vector2(0.0f), Vector2(1.0f));
@ -424,7 +424,7 @@ namespace TEN::Renderer
texture2DPtr->GetDesc(&desc); texture2DPtr->GetDesc(&desc);
float screenAspect = float(_screenWidth) / float(_screenHeight); float screenAspect = float(_screenWidth) / float(_screenHeight);
float imageAspect = float(desc.Width) / float(desc.Height); float imageAspect = customAspect == 0.0f ? float(desc.Width) / float(desc.Height) : customAspect;
if (screenAspect > imageAspect) if (screenAspect > imageAspect)
{ {
@ -584,7 +584,11 @@ namespace TEN::Renderer
for (const auto& displaySprite : DisplaySprites) for (const auto& displaySprite : DisplaySprites)
{ {
const auto& sprite = _sprites[Objects[displaySprite.ObjectID].meshIndex + displaySprite.SpriteID]; // If sprite is a video texture, bypass it if texture is inactive.
if (displaySprite.SpriteID == VIDEO_SPRITE_ID && (_videoSprite.Texture == nullptr || _videoSprite.Texture->Texture == nullptr))
continue;
const auto& sprite = displaySprite.SpriteID == VIDEO_SPRITE_ID ? _videoSprite : _sprites[Objects[displaySprite.ObjectID].meshIndex + displaySprite.SpriteID];
// Calculate sprite aspect ratio. // Calculate sprite aspect ratio.
float spriteAspect = (float)sprite.Width / (float)sprite.Height; float spriteAspect = (float)sprite.Width / (float)sprite.Height;

View file

@ -556,12 +556,18 @@ namespace TEN::Renderer
} }
} }
// If sprite is a video texture, bypass it if texture is inactive.
if (particle.SpriteID == VIDEO_SPRITE_ID && (_videoSprite.Texture == nullptr || _videoSprite.Texture->Texture == nullptr))
continue;
// Disallow sprites out of bounds. // Disallow sprites out of bounds.
int spriteIndex = Objects[particle.SpriteSeqID].meshIndex + particle.SpriteID; int spriteIndex = Objects[particle.SpriteSeqID].meshIndex + particle.SpriteID;
spriteIndex = std::clamp(spriteIndex, 0, (int)_sprites.size()); spriteIndex = std::clamp(spriteIndex, 0, (int)_sprites.size());
auto* sprite = particle.SpriteID == VIDEO_SPRITE_ID ? &_videoSprite : &_sprites[spriteIndex];
AddSpriteBillboard( AddSpriteBillboard(
&_sprites[spriteIndex], sprite,
pos, pos,
Color(particle.r / (float)UCHAR_MAX, particle.g / (float)UCHAR_MAX, particle.b / (float)UCHAR_MAX, 1.0f), Color(particle.r / (float)UCHAR_MAX, particle.g / (float)UCHAR_MAX, particle.b / (float)UCHAR_MAX, 1.0f),
TO_RAD(particle.rotAng << 4), particle.scalar, TO_RAD(particle.rotAng << 4), particle.scalar,

View file

@ -903,7 +903,7 @@ namespace TEN::Renderer
if (!texture.Texture) if (!texture.Texture)
return; return;
int timeout = 10; int timeout = 20;
float currentFade = FADE_FACTOR; float currentFade = FADE_FACTOR;
while (timeout || currentFade > 0.0f) while (timeout || currentFade > 0.0f)

View file

@ -12,21 +12,24 @@
#include "Specific/configuration.h" #include "Specific/configuration.h"
#include "Specific/memory/Vector.h" #include "Specific/memory/Vector.h"
#include "Specific/trutils.h" #include "Specific/trutils.h"
#include "Specific/Video/Video.h"
#include "Specific/winmain.h" #include "Specific/winmain.h"
extern GameConfiguration g_Configuration; extern GameConfiguration g_Configuration;
using namespace TEN::Renderer::Utils; using namespace TEN::Renderer::Utils;
using namespace TEN::Video;
namespace TEN::Renderer namespace TEN::Renderer
{ {
void Renderer::Initialize(int w, int h, bool windowed, HWND handle) void Renderer::Initialize(const std::string& gameDir, int w, int h, bool windowed, HWND handle)
{ {
TENLog("Initializing DX11...", LogLevel::Info); TENLog("Initializing DX11...", LogLevel::Info);
_screenWidth = w; _screenWidth = w;
_screenHeight = h; _screenHeight = h;
_isWindowed = windowed; _isWindowed = windowed;
InitializeScreen(w, h, handle, false); InitializeScreen(w, h, handle, false);
InitializeCommonTextures(); InitializeCommonTextures();
@ -230,6 +233,9 @@ namespace TEN::Renderer
_sortedPolygonsIndices.reserve(MAX_TRANSPARENT_VERTICES); _sortedPolygonsIndices.reserve(MAX_TRANSPARENT_VERTICES);
_sortedPolygonsVertexBuffer = VertexBuffer<Vertex>(_device.Get(), MAX_TRANSPARENT_VERTICES, _sortedPolygonsVertices); _sortedPolygonsVertexBuffer = VertexBuffer<Vertex>(_device.Get(), MAX_TRANSPARENT_VERTICES, _sortedPolygonsVertices);
_sortedPolygonsIndexBuffer = IndexBuffer(_device.Get(), MAX_TRANSPARENT_VERTICES, _sortedPolygonsIndices); _sortedPolygonsIndexBuffer = IndexBuffer(_device.Get(), MAX_TRANSPARENT_VERTICES, _sortedPolygonsIndices);
// Initialize video player.
g_VideoPlayer.Initialize(gameDir, _device.Get(), _context.Get());
} }
void Renderer::InitializePostProcess() void Renderer::InitializePostProcess()

View file

@ -8,5 +8,6 @@ namespace TEN::Renderer::Structures
struct RendererAnimatedTexture struct RendererAnimatedTexture
{ {
Vector2 UV[4]; Vector2 UV[4];
Vector2 NormalizedUV[4];
}; };
} }

View file

@ -6,10 +6,18 @@ namespace TEN::Renderer::Structures
{ {
using namespace DirectX::SimpleMath; using namespace DirectX::SimpleMath;
enum class AnimatedTextureType
{
Frames,
UVRotate,
Video
};
struct RendererAnimatedTextureSet struct RendererAnimatedTextureSet
{ {
int NumTextures; AnimatedTextureType Type = AnimatedTextureType::Frames;
int Fps; int NumTextures = 0;
int Fps = 0;
std::vector<RendererAnimatedTexture> Textures; std::vector<RendererAnimatedTexture> Textures;
}; };
} }

View file

@ -7,6 +7,8 @@ namespace TEN::Renderer::Structures
using namespace TEN::Renderer::Graphics; using namespace TEN::Renderer::Graphics;
using namespace DirectX::SimpleMath; using namespace DirectX::SimpleMath;
constexpr int VIDEO_SPRITE_ID = NO_VALUE;
struct RendererSprite struct RendererSprite
{ {
int Index; int Index;

View file

@ -13,6 +13,7 @@ public:
FreezeMode CurrentFreezeMode = FreezeMode::None; FreezeMode CurrentFreezeMode = FreezeMode::None;
std::string IntroImagePath = {}; std::string IntroImagePath = {};
std::string IntroVideoPath = {};
std::string TitleScreenImagePath = {}; std::string TitleScreenImagePath = {};
int SelectedLevelForNewGame = 0; int SelectedLevelForNewGame = 0;

View file

@ -220,6 +220,7 @@ static constexpr char ScriptReserved_AddLevel[] = "AddLevel";
static constexpr char ScriptReserved_GetLevel[] = "GetLevel"; static constexpr char ScriptReserved_GetLevel[] = "GetLevel";
static constexpr char ScriptReserved_GetCurrentLevel[] = "GetCurrentLevel"; static constexpr char ScriptReserved_GetCurrentLevel[] = "GetCurrentLevel";
static constexpr char ScriptReserved_SetIntroImagePath[] = "SetIntroImagePath"; static constexpr char ScriptReserved_SetIntroImagePath[] = "SetIntroImagePath";
static constexpr char ScriptReserved_SetIntroVideoPath[] = "SetIntroVideoPath";
static constexpr char ScriptReserved_SetTitleScreenImagePath[] = "SetTitleScreenImagePath"; static constexpr char ScriptReserved_SetTitleScreenImagePath[] = "SetTitleScreenImagePath";
static constexpr char ScriptReserved_SetFarView[] = "SetFarView"; static constexpr char ScriptReserved_SetFarView[] = "SetFarView";
static constexpr char ScriptReserved_SetAnimations[] = "SetAnimations"; static constexpr char ScriptReserved_SetAnimations[] = "SetAnimations";
@ -352,6 +353,12 @@ static constexpr char ScriptReserved_KeyClearAll[] = "KeyClearAll";
static constexpr char ScriptReserved_FlipMap[] = "FlipMap"; static constexpr char ScriptReserved_FlipMap[] = "FlipMap";
static constexpr char ScriptReserved_GetFlipMapStatus[] = "GetFlipMapStatus"; static constexpr char ScriptReserved_GetFlipMapStatus[] = "GetFlipMapStatus";
static constexpr char ScriptReserved_PlayVideo[] = "PlayVideo";
static constexpr char ScriptReserved_StopVideo[] = "StopVideo";
static constexpr char ScriptReserved_IsVideoPlaying[] = "IsVideoPlaying";
static constexpr char ScriptReserved_GetVideoPosition[] = "GetVideoPosition";
static constexpr char ScriptReserved_SetVideoPosition[] = "SetVideoPosition";
static constexpr char ScriptReserved_GetVideoDominantColor[] = "GetVideoDominantColor";
static constexpr char ScriptReserved_PlayFlyby[] = "PlayFlyby"; static constexpr char ScriptReserved_PlayFlyby[] = "PlayFlyby";
static constexpr char ScriptReserved_GetFlybyPosition[] = "GetFlybyPosition"; static constexpr char ScriptReserved_GetFlybyPosition[] = "GetFlybyPosition";
static constexpr char ScriptReserved_GetFlybyRotation[] = "GetFlybyRotation"; static constexpr char ScriptReserved_GetFlybyRotation[] = "GetFlybyRotation";

View file

@ -67,6 +67,13 @@ Must be a .jpg or .png image.
*/ */
tableFlow.set_function(ScriptReserved_SetIntroImagePath, &FlowHandler::SetIntroImagePath, this); tableFlow.set_function(ScriptReserved_SetIntroImagePath, &FlowHandler::SetIntroImagePath, this);
/*** Video to show when loading the game.
Must be a common video format, such as .mp4, .mkv or .avi.
@function SetIntroVideoPath
@tparam string path the path to the video, relative to the TombEngine exe
*/
tableFlow.set_function(ScriptReserved_SetIntroVideoPath, &FlowHandler::SetIntroVideoPath, this);
/*** Image to show in the background of the title screen. /*** Image to show in the background of the title screen.
Must be a .jpg or .png image. Must be a .jpg or .png image.
__(not yet implemented)__ __(not yet implemented)__
@ -407,11 +414,17 @@ void FlowHandler::SetIntroImagePath(const std::string& path)
IntroImagePath = path; IntroImagePath = path;
} }
void FlowHandler::SetIntroVideoPath(const std::string& path)
{
IntroVideoPath = path;
}
void FlowHandler::SetTitleScreenImagePath(const std::string& path) void FlowHandler::SetTitleScreenImagePath(const std::string& path)
{ {
TitleScreenImagePath = path; TitleScreenImagePath = path;
} }
int FlowHandler::GetTotalSecretCount() int FlowHandler::GetTotalSecretCount()
{ {
return TotalNumberOfSecrets; return TotalNumberOfSecrets;

View file

@ -69,6 +69,7 @@ public:
void SetSecretCount(int secretsNum); void SetSecretCount(int secretsNum);
void AddSecret(int levelSecretIndex); void AddSecret(int levelSecretIndex);
void SetIntroImagePath(const std::string& path); void SetIntroImagePath(const std::string& path);
void SetIntroVideoPath(const std::string& path);
void SetTitleScreenImagePath(const std::string& path); void SetTitleScreenImagePath(const std::string& path);
int GetTotalSecretCount(); int GetTotalSecretCount();
void SetTotalSecretCount(int secretsNumber); void SetTotalSecretCount(int secretsNumber);

View file

@ -14,7 +14,7 @@
namespace TEN::Scripting::Sound namespace TEN::Scripting::Sound
{ {
/// Play an audio track. Supported formats are wav, mp3 and ogg. /// Play an audio track. Should be placed in the `Audio` folder. Supported formats are wav, mp3 and ogg.
// @function PlayAudioTrack // @function PlayAudioTrack
// @tparam string filename Filename of a track (without file extension) to play. // @tparam string filename Filename of a track (without file extension) to play.
// @tparam Sound.SoundTrackType type Type of the audio track to play. // @tparam Sound.SoundTrackType type Type of the audio track to play.

View file

@ -25,7 +25,9 @@ namespace TEN::Scripting::DisplaySprite
// NOTE: Single constructor with a sol::optional argument for the color doesn't work, hence the two constructors. -- Sezz 2023.10.19 // NOTE: Single constructor with a sol::optional argument for the color doesn't work, hence the two constructors. -- Sezz 2023.10.19
using ctors = sol::constructors< using ctors = sol::constructors<
ScriptDisplaySprite(GAME_OBJECT_ID, int, const Vec2&, float, const Vec2&, const ScriptColor&), ScriptDisplaySprite(GAME_OBJECT_ID, int, const Vec2&, float, const Vec2&, const ScriptColor&),
ScriptDisplaySprite(GAME_OBJECT_ID, int, const Vec2&, float, const Vec2&)>; ScriptDisplaySprite(GAME_OBJECT_ID, int, const Vec2&, float, const Vec2&),
ScriptDisplaySprite(const Vec2&, float, const Vec2&, const ScriptColor&),
ScriptDisplaySprite(const Vec2&, float, const Vec2&)>;
// Register type. // Register type.
parent.new_usertype<ScriptDisplaySprite>( parent.new_usertype<ScriptDisplaySprite>(
@ -49,7 +51,7 @@ namespace TEN::Scripting::DisplaySprite
} }
/// Create a DisplaySprite object. /// Create a DisplaySprite object.
// @function DisplaySprite() // @function DisplaySprite
// @tparam Objects.ObjID.SpriteConstants ID of the sprite sequence object. // @tparam Objects.ObjID.SpriteConstants ID of the sprite sequence object.
// @tparam int int spriteID ID of the sprite in the sequence. // @tparam int int spriteID ID of the sprite in the sequence.
// @tparam Vec2 pos Display position in percent. // @tparam Vec2 pos Display position in percent.
@ -60,7 +62,7 @@ namespace TEN::Scripting::DisplaySprite
ScriptDisplaySprite::ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale, const ScriptColor& color) ScriptDisplaySprite::ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale, const ScriptColor& color)
{ {
_objectID = objectID; _objectID = objectID;
_spriteID = spriteID; _spriteID = std::clamp(spriteID, 0, INT_MAX);
_position = pos; _position = pos;
_rotation = rot; _rotation = rot;
_scale = scale; _scale = scale;
@ -69,9 +71,30 @@ namespace TEN::Scripting::DisplaySprite
ScriptDisplaySprite::ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale) ScriptDisplaySprite::ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale)
{ {
static const auto DEFAULT_COLOR = ScriptColor(255, 255, 255, 255); *this = ScriptDisplaySprite(objectID, spriteID, pos, rot, scale, ScriptColor(255, 255, 255, 255));
}
*this = ScriptDisplaySprite(objectID, spriteID, pos, rot, scale, DEFAULT_COLOR); /// Create a DisplaySprite object with a video image.
// Video should be played using @{View.PlayVideo} function in a background mode. If no video is played, sprite will not show.
// @function DisplaySprite
// @tparam Vec2 pos Display position in percent.
// @tparam float rot Rotation in degrees.
// @tparam Vec2 scale Horizontal and vertical scale in percent. Scaling is interpreted by the DisplaySpriteEnum.ScaleMode passed to the Draw() function call.
// @tparam[opt] Color color Color. __Default: Color(255, 255, 255, 255)__
// @treturn DisplaySprite A new DisplaySprite object with attached video image.
ScriptDisplaySprite::ScriptDisplaySprite(const Vec2& pos, float rot, const Vec2& scale, const ScriptColor& color)
{
_objectID = GAME_OBJECT_ID::ID_DEFAULT_SPRITES;
_spriteID = VIDEO_SPRITE_ID;
_position = pos;
_rotation = rot;
_scale = scale;
_color = color;
}
ScriptDisplaySprite::ScriptDisplaySprite(const Vec2& pos, float rot, const Vec2& scale)
{
*this = ScriptDisplaySprite(pos, rot, scale, ScriptColor(255, 255, 255, 255));
} }
/// Get the object ID of the sprite sequence object used by the display sprite. /// Get the object ID of the sprite sequence object used by the display sprite.
@ -84,7 +107,7 @@ namespace TEN::Scripting::DisplaySprite
/// Get the sprite ID in the sprite sequence object used by the display sprite. /// Get the sprite ID in the sprite sequence object used by the display sprite.
// @function DisplaySprite:GetSpriteID() // @function DisplaySprite:GetSpriteID()
// @treturn int Sprite ID in the sprite sequence object. // @treturn int Sprite ID in the sprite sequence object. Value __-1__ means that it is a background video, played using @{View.PlayVideo}.
int ScriptDisplaySprite::GetSpriteID() const int ScriptDisplaySprite::GetSpriteID() const
{ {
return _spriteID; return _spriteID;
@ -190,7 +213,7 @@ namespace TEN::Scripting::DisplaySprite
constexpr auto DEFAULT_BLEND_MODE = BlendMode::AlphaBlend; constexpr auto DEFAULT_BLEND_MODE = BlendMode::AlphaBlend;
// Object is not a sprite sequence; return early. // Object is not a sprite sequence; return early.
if (_objectID < GAME_OBJECT_ID::ID_HORIZON || _objectID >= GAME_OBJECT_ID::ID_NUMBER_OBJECTS) if (_spriteID != VIDEO_SPRITE_ID && (_objectID < GAME_OBJECT_ID::ID_HORIZON || _objectID >= GAME_OBJECT_ID::ID_NUMBER_OBJECTS))
{ {
TENLog("Attempted to draw display sprite from non-sprite sequence object " + std::to_string(_objectID), LogLevel::Warning); TENLog("Attempted to draw display sprite from non-sprite sequence object " + std::to_string(_objectID), LogLevel::Warning);
return; return;

View file

@ -31,6 +31,8 @@ namespace TEN::Scripting::DisplaySprite
// Constructors // Constructors
ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale, const ScriptColor& color); ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale, const ScriptColor& color);
ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale); ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale);
ScriptDisplaySprite(const Vec2& pos, float rot, const Vec2& scale, const ScriptColor& color);
ScriptDisplaySprite(const Vec2& pos, float rot, const Vec2& scale);
// Getters // Getters
GAME_OBJECT_ID GetObjectID() const; GAME_OBJECT_ID GetObjectID() const;

View file

@ -12,6 +12,7 @@
#include "Scripting/Internal/TEN/Objects/Room/RoomObject.h" #include "Scripting/Internal/TEN/Objects/Room/RoomObject.h"
#include "Scripting/Internal/TEN/Types/Color/Color.h" #include "Scripting/Internal/TEN/Types/Color/Color.h"
#include "Scripting/Internal/TEN/Types/Rotation/Rotation.h" #include "Scripting/Internal/TEN/Types/Rotation/Rotation.h"
#include "Scripting/Internal/TEN/Types/Time/Time.h"
#include "Scripting/Internal/TEN/Types/Vec3/Vec3.h" #include "Scripting/Internal/TEN/Types/Vec3/Vec3.h"
#include "Scripting/Internal/TEN/View/AlignModes.h" #include "Scripting/Internal/TEN/View/AlignModes.h"
#include "Scripting/Internal/TEN/View/CameraTypes.h" #include "Scripting/Internal/TEN/View/CameraTypes.h"
@ -19,10 +20,14 @@
#include "Scripting/Internal/TEN/View/ScaleModes.h" #include "Scripting/Internal/TEN/View/ScaleModes.h"
#include "Scripting/Internal/TEN/View/PostProcessEffects.h" #include "Scripting/Internal/TEN/View/PostProcessEffects.h"
#include "Specific/clock.h" #include "Specific/clock.h"
#include "Specific/Video/Video.h"
#include "Specific/trutils.h"
using namespace TEN::Effects::Environment; using namespace TEN::Effects::Environment;
using namespace TEN::Scripting::DisplaySprite; using namespace TEN::Scripting::DisplaySprite;
using namespace TEN::Scripting::View; using namespace TEN::Scripting::View;
using namespace TEN::Utils;
using namespace TEN::Video;
using TEN::Renderer::g_Renderer; using TEN::Renderer::g_Renderer;
@ -111,6 +116,59 @@ namespace TEN::Scripting::View
InitializeSpotCam(seqID); InitializeSpotCam(seqID);
} }
static void PlayVideo(const std::string& fileName, TypeOrNil<bool> background, TypeOrNil<bool> silent, TypeOrNil<bool> loop)
{
auto mode = ValueOr<bool>(background, false) ? VideoPlaybackMode::Background : VideoPlaybackMode::Exclusive;
g_VideoPlayer.Play(fileName, mode, ValueOr<bool>(silent, false), ValueOr<bool>(loop, false));
}
static void StopVideo()
{
g_VideoPlayer.Stop();
}
static Time GetVideoPosition()
{
if (!g_VideoPlayer.IsPlaying())
{
TENLog("Attempted to get video position while video is not playing.", LogLevel::Warning);
return 0;
}
return g_VideoPlayer.GetPosition();
}
static void SetVideoPosition(Time frameCount)
{
if (!g_VideoPlayer.IsPlaying())
{
TENLog("Attempted to set video position while video is not playing.", LogLevel::Warning);
return;
}
g_VideoPlayer.SetPosition(frameCount);
return;
}
static ScriptColor GetVideoDominantColor()
{
return g_VideoPlayer.GetDominantColor();
}
static bool IsVideoPlaying(sol::optional<std::string> name)
{
bool isPlaying = g_VideoPlayer.IsPlaying();
if (!isPlaying || !name.has_value())
return isPlaying;
// Get the current playing video filename from the full path.
auto filePath = std::filesystem::path(g_VideoPlayer.GetFileName());
auto currentVideoName = ToLower(filePath.filename().string());
return (currentVideoName == ToLower(name.value()));
}
static Vec3 GetFlybyPosition(int seqID, float progress, TypeOrNil<bool> loop) static Vec3 GetFlybyPosition(int seqID, float progress, TypeOrNil<bool> loop)
{ {
constexpr auto PROGRESS_MAX = 100.0f; constexpr auto PROGRESS_MAX = 100.0f;
@ -180,8 +238,8 @@ namespace TEN::Scripting::View
///Move black cinematic bars in from the top and bottom of the game window. ///Move black cinematic bars in from the top and bottom of the game window.
//@function SetCineBars //@function SetCineBars
//@tparam float height __(default 30)__ Percentage of the screen to be covered //@tparam float height (default 30). Percentage of the screen to be covered
//@tparam float speed __(default 30)__ Coverage percent per second //@tparam float speed (default 30). Coverage percent per second
tableView.set_function(ScriptReserved_SetCineBars, &SetCineBars); tableView.set_function(ScriptReserved_SetCineBars, &SetCineBars);
///Set field of view. ///Set field of view.
@ -235,6 +293,40 @@ namespace TEN::Scripting::View
//@tparam Color tint value to use. //@tparam Color tint value to use.
tableView.set_function(ScriptReserved_SetPostProcessTint, &SetPostProcessTint); tableView.set_function(ScriptReserved_SetPostProcessTint, &SetPostProcessTint);
/// Play a video file. File should be placed in the `FMV` folder.
// @function PlayVideo
// @tparam string fileName Video file name. Can be provided without extension, if type is mp4, mkv or avi.
// @tparam[opt] bool background (default: false). Play video in the background mode.
// In such case, video won't play in fullscreen, but must be shown using special animated texture type in Tomb Editor, or using @{View.DisplaySprite}.
// @tparam[opt] bool silent (default: false). Play video without sound.
// @tparam[opt] bool loop (default: false). Play video in a loop.
tableView.set_function(ScriptReserved_PlayVideo, &PlayVideo);
/// Stop the currently playing video. Only possible if video is playing in the background mode.
// @function StopVideo
tableView.set_function(ScriptReserved_StopVideo, &StopVideo);
/// Gets the currently playing video position.
// @function GetVideoPosition
// @treturn Time Current video position.
tableView.set_function(ScriptReserved_GetVideoPosition, &GetVideoPosition);
/// Sets the currently playing video position.
// @function SetVideoPosition
// @tparam Time position New video position.
tableView.set_function(ScriptReserved_SetVideoPosition, &SetVideoPosition);
/// Gets the dominant color for the current video frame. If no video is playing, returns black.
// @function GetVideoDominantColor
// @treturn Color Dominant video color.
tableView.set_function(ScriptReserved_GetVideoDominantColor, &GetVideoDominantColor);
/// Checks if video is currently playing.
// @function IsVideoPlaying
// @tparam[opt] string name Video file name. If provided, checks if the currently playing video file name is the same as the provided one.
// @treturn bool True if video is currently playing.
tableView.set_function(ScriptReserved_IsVideoPlaying, &IsVideoPlaying);
/// Play a flyby sequence. /// Play a flyby sequence.
// @function PlayFlyby // @function PlayFlyby
// @tparam int seqID Flyby sequence ID. // @tparam int seqID Flyby sequence ID.

View file

@ -15,10 +15,12 @@
#include "Specific/configuration.h" #include "Specific/configuration.h"
#include "Specific/level.h" #include "Specific/level.h"
#include "Specific/trutils.h" #include "Specific/trutils.h"
#include "Specific/Video/Video.h"
#include "Specific/winmain.h" #include "Specific/winmain.h"
using namespace TEN::Gui; using namespace TEN::Gui;
using namespace TEN::Math; using namespace TEN::Math;
using namespace TEN::Video;
enum SoundSourceFlags enum SoundSourceFlags
{ {
@ -76,6 +78,7 @@ void SetVolumeTracks(int vol)
void SetVolumeFX(int vol) void SetVolumeFX(int vol)
{ {
GlobalFXVolume = vol; GlobalFXVolume = vol;
g_VideoPlayer.SetVolume(vol);
} }
bool LoadSample(char* pointer, int compSize, int uncompSize, int index) bool LoadSample(char* pointer, int compSize, int uncompSize, int index)

View file

@ -167,6 +167,8 @@ namespace TEN::Input
void DeinitializeInput() void DeinitializeInput()
{ {
TENLog("Shutting down OIS...", LogLevel::Info);
if (OisKeyboard != nullptr) if (OisKeyboard != nullptr)
OisInputManager->destroyInputObject(OisKeyboard); OisInputManager->destroyInputObject(OisKeyboard);
@ -650,10 +652,10 @@ namespace TEN::Input
RumbleInfo.LastPower = RumbleInfo.Power; RumbleInfo.LastPower = RumbleInfo.Power;
} }
void UpdateInputActions(ItemInfo* item, bool applyQueue) void UpdateInputActions(bool allowAsyncUpdate, bool applyQueue)
{ {
// Don't update input data during frameskip. // Don't update input data during frameskip.
if (!g_Synchronizer.Locked()) if (allowAsyncUpdate || !g_Synchronizer.Locked())
{ {
ClearInputData(); ClearInputData();
UpdateRumble(); UpdateRumble();

View file

@ -51,7 +51,7 @@ namespace TEN::Input
void InitializeInput(HWND handle); void InitializeInput(HWND handle);
void DeinitializeInput(); void DeinitializeInput();
void DefaultConflict(); void DefaultConflict();
void UpdateInputActions(ItemInfo* item, bool applyQueue = false); void UpdateInputActions(bool allowAsyncUpdate = false, bool applyQueue = false);
void ApplyActionQueue(); void ApplyActionQueue();
void ClearAllActions(); void ClearAllActions();
void Rumble(float power, float delayInSec = 0.3f, RumbleMode mode = RumbleMode::Both); void Rumble(float power, float delayInSec = 0.3f, RumbleMode mode = RumbleMode::Both);

View file

@ -0,0 +1,622 @@
#include "framework.h"
#include "Specific/Video/Video.h"
#include "Renderer/Renderer.h"
#include "Sound/sound.h"
#include "Specific/Input/Input.h"
#include "Specific/winmain.h"
using namespace TEN::Input;
namespace TEN::Video
{
VideoHandler g_VideoPlayer = {};
static const std::string VIDEO_PATH = "FMV/";
static const std::vector<std::string> VIDEO_EXTENSIONS = { ".mp4", ".avi", ".mkv", ".mov" };
int VideoHandler::GetPosition() const
{
if (_player == nullptr)
return 0;
auto* media = libvlc_media_player_get_media(_player);
long long duration = libvlc_media_get_duration(media);
float posNormalized = GetNormalizedPosition();
// Convert and return position in frames.
long long posMsec = posNormalized * duration;
return (int)((posMsec / 1000.0f) * FPS);
}
float VideoHandler::GetNormalizedPosition() const
{
if (_player == nullptr)
return 0.0f;
return (float)libvlc_media_player_get_position(_player);
}
std::string VideoHandler::GetFileName() const
{
if (_player == nullptr)
return std::string();
return _fileName;
}
Color VideoHandler::GetDominantColor() const
{
if (_player == nullptr || _frameBuffer.size() == 0)
return Color(0.0f, 0.0f, 0.0f);
unsigned long long accR = 0;
unsigned long long accG = 0;
unsigned long long accB = 0;
int pixelCount = 0;
int step = 8;
for (int y = 0; y < _size.y; y += step)
{
for (int x = 0; x < _size.x; x += step)
{
int index = (y * (x * 4)) + (x * 4);
unsigned char b = _frameBuffer[index];
unsigned char g = _frameBuffer[index + 1];
unsigned char r = _frameBuffer[index + 2];
accR += r;
accG += g;
accB += b;
pixelCount++;
}
}
if (pixelCount == 0)
return Color(0.0f, 0.0f, 0.0f);
unsigned char avgR = unsigned char(accR / pixelCount);
unsigned char avgG = unsigned char(accG / pixelCount);
unsigned char avgB = unsigned char(accB / pixelCount);
auto result = Vector3((float)avgR / 255.0f, (float)avgG / 255.0f, (float)avgB / 255.0f);
float luma = Luma(result);
if (luma < 0.3f && luma > 0.0f)
{
float boostFactor = 0.3f / luma;
result *= boostFactor;
result.Clamp(Vector3::Zero, Vector3::One);
}
if (luma < 0.5f)
{
float desaturationFactor = (0.4f - luma) / 0.4f;
result.x = (result.x * (1.0f - desaturationFactor)) + (luma * desaturationFactor);
result.y = (result.y * (1.0f - desaturationFactor)) + (luma * desaturationFactor);
result.z = (result.z * (1.0f - desaturationFactor)) + (luma * desaturationFactor);
}
return Color(result);
}
bool VideoHandler::GetSilent() const
{
return _silent;
}
bool VideoHandler::GetLooped() const
{
return _looped;
}
void VideoHandler::SetPosition(int frameCount)
{
if (_player == nullptr)
return;
auto* media = libvlc_media_player_get_media(_player);
long long duration = libvlc_media_get_duration(media);
// Convert frames to time in milliseconds (assuming 30 FPS).
float posMsec = (frameCount / FPS) * 1000.0f;
float posNormalized = posMsec / (float)(duration);
if (posNormalized > 1.0f)
{
TENLog("Video position is out of bounds.", LogLevel::Warning);
return;
}
// Set normalized position.
SetNormalizedPosition(posNormalized);
HandleError();
}
void VideoHandler::SetNormalizedPosition(float pos)
{
if (_player == nullptr)
return;
libvlc_media_player_set_position(_player, std::clamp(pos, 0.0f, 1.0f), false);
HandleError();
}
void VideoHandler::SetVolume(int volume)
{
// Set volume even if player is not available because volume may be externally changed from settings.
_volume = std::clamp(volume, 0, 100);
if (_player != nullptr)
libvlc_audio_set_volume(_player, _silent ? 0.0f : _volume);
HandleError();
}
bool VideoHandler::IsPlaying() const
{
if (_player == nullptr)
return false;
auto state = libvlc_media_player_get_state(_player);
return (state == libvlc_Playing);
}
void VideoHandler::Initialize(const std::string& gameDir, ID3D11Device* device, ID3D11DeviceContext* context)
{
TENLog("Initializing video player...", LogLevel::Info);
// Disable video output and title because rendering is done to a D3D texture.
#ifdef _DEBUG
const char* args[] = { "--vout=none", "--no-video-title", "--no-media-library"};
_vlcInstance = libvlc_new(3, args);
//libvlc_log_set(_vlcInstance, OnLog, nullptr);
#else
const char* args[] = { "--vout=none", "--no-video-title", "--no-media-library", "--quiet" };
_vlcInstance = libvlc_new(4, args);
#endif
HandleError();
_d3dDevice = device;
_d3dContext = context;
_videoDirectory = gameDir + VIDEO_PATH;
_size = Vector2i::Zero;
_fileName = {};
_playbackMode = VideoPlaybackMode::Exclusive;
_looped = false;
_silent = false;
}
void VideoHandler::DeInitialize()
{
TENLog("Shutting down VLC...", LogLevel::Info);
// This flag is needed to avoid race conditions with update callbacks.
_deInitializing = true;
if (_player != nullptr)
{
if (libvlc_media_player_is_playing(_player))
libvlc_media_player_stop_async(_player);
while (libvlc_media_player_is_playing(_player))
std::this_thread::sleep_for(std::chrono::milliseconds(10));
libvlc_media_player_release(_player);
_player = nullptr;
}
if (_vlcInstance)
libvlc_release(_vlcInstance);
_vlcInstance = nullptr;
}
bool VideoHandler::Play(const std::string& filename, VideoPlaybackMode mode, bool silent, bool loop)
{
auto fullVideoName = filename;
// At first, attempt to load video file with original filename. Then proceed with asset directory.
// Then, if not found, try all common video file extensions, and only quit if none are found.
if (!std::filesystem::is_regular_file(fullVideoName))
{
fullVideoName = _videoDirectory + filename;
if (!std::filesystem::is_regular_file(fullVideoName))
{
for (const auto& ext : VIDEO_EXTENSIONS)
{
if (std::filesystem::is_regular_file(fullVideoName + ext))
{
fullVideoName += ext;
break;
}
}
if (!std::filesystem::is_regular_file(fullVideoName))
{
TENLog("Video file " + fullVideoName + " not found.", LogLevel::Warning);
return false;
}
}
}
// Don't start playback if same video is already playing.
if (_player != nullptr)
{
if (libvlc_media_player_get_state(_player) == libvlc_Playing &&
_playbackMode == mode && _fileName == fullVideoName)
{
TENLog("Video file " + fullVideoName + " is already playing.", LogLevel::Warning);
return false;
}
}
// Stop previous player instance if it exists.
Stop();
_looped = loop;
_silent = silent;
_playbackMode = mode;
_fileName = fullVideoName;
_needRender = _updateInput = false;
auto* media = libvlc_media_new_path(_fileName.c_str());
if (media == nullptr)
{
TENLog("Failed to create media from path: " + _fileName, LogLevel::Error);
return false;
}
// VLC requires to initialize media. Load into player and release right away.
_player = libvlc_media_player_new_from_media(_vlcInstance, media);
libvlc_media_release(media);
if (_player == nullptr)
{
TENLog("Failed to create media player.", LogLevel::Error);
return false;
}
libvlc_video_set_callbacks(_player, OnLockFrame, OnUnlockFrame, nullptr, this);
libvlc_video_set_format_callbacks(_player, OnSetup, nullptr);
libvlc_media_player_play(_player);
SetVolume(_volume);
if (!HandleError())
return false;
auto filePath = std::filesystem::path(_fileName);
TENLog("Playing video file: " + filePath.filename().string() + " (" + (mode == VideoPlaybackMode::Exclusive ? "Exclusive" : "Background") + " mode)", LogLevel::Info);
if (_playbackMode == VideoPlaybackMode::Exclusive)
PauseAllSounds(SoundPauseMode::Global);
return true;
}
bool VideoHandler::Pause()
{
if (_player == nullptr)
return false;
if (libvlc_media_player_get_state(_player) != libvlc_Paused)
{
libvlc_media_player_pause(_player);
HandleError();
return (_playbackMode == VideoPlaybackMode::Exclusive);
}
HandleError();
return false;
}
bool VideoHandler::Resume()
{
if (_player == nullptr)
return false;
if (libvlc_media_player_get_state(_player) == libvlc_Paused)
{
libvlc_media_player_play(_player);
HandleError();
return (_playbackMode == VideoPlaybackMode::Exclusive);
}
HandleError();
return false;
}
void VideoHandler::Stop()
{
DeinitializePlayer();
DeinitializeD3DTexture();
// Don't unset this flag until D3D texture is released, otherwise it may crash when trying to render the texture.
_needRender = false;
HandleError();
}
bool VideoHandler::Update()
{
if (_deInitializing || _player == nullptr)
return false;
// Attempt to map and render texture only if callback has set frame to be rendered.
if (_needRender)
{
auto mappedResource = D3D11_MAPPED_SUBRESOURCE{};
if (_videoTexture && SUCCEEDED(_d3dContext->Map(_videoTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource)))
{
// Copy framebuffer row by row, otherwise skewing may occur.
unsigned char* pData = reinterpret_cast<unsigned char*>(mappedResource.pData);
for (int row = 0; row < _size.y; row++)
memcpy(pData + row * mappedResource.RowPitch, _frameBuffer.data() + row * _size.x * 4, _size.x * 4);
_d3dContext->Unmap(_videoTexture, 0);
if (_playbackMode == VideoPlaybackMode::Exclusive)
{
RenderExclusive();
}
else if (_playbackMode == VideoPlaybackMode::Background)
{
RenderBackground();
}
}
else
{
TENLog("Failed to render video texture", LogLevel::Error);
}
_needRender = false;
}
if (_playbackMode == VideoPlaybackMode::Exclusive)
{
UpdateExclusive();
}
else if (_playbackMode == VideoPlaybackMode::Background)
{
UpdateBackground();
}
return (_playbackMode == VideoPlaybackMode::Exclusive);
}
void VideoHandler::UpdateExclusive()
{
if (_deInitializing || _player == nullptr)
return;
bool interruptPlayback = false;
if (_updateInput)
{
App.ResetClock = true;
UpdateInputActions(true);
interruptPlayback = IsHeld(In::Deselect) || IsHeld(In::Look);
_updateInput = false;
}
auto state = libvlc_media_player_get_state(_player);
// If player is just opening, buffering, or stopping, always return early and wait for process to end.
if (state == libvlc_Opening || state == libvlc_Buffering)
return;
// Reset playback to start if video is looped.
if (_looped && !interruptPlayback && (state == libvlc_Stopping || state == libvlc_Stopped))
libvlc_media_player_play(_player);
// If user pressed a key to break out from video or video has finished playback or in an error, stop and delete it.
if (interruptPlayback || state == libvlc_Error || state == libvlc_Stopped)
{
Stop();
ClearAction(In::Pause); // HACK: Otherwise pause key won't work after video ends.
ResumeAllSounds(SoundPauseMode::Global);
}
HandleError();
}
void VideoHandler::RenderExclusive()
{
g_Renderer.RenderFullScreenTexture(_textureView, (float)_size.x / (float)_size.y);
}
void VideoHandler::UpdateBackground()
{
if (_deInitializing || _player == nullptr)
return;
auto state = libvlc_media_player_get_state(_player);
// If video has finished playback, stop and delete it.
if (!_looped && (state == libvlc_Error || state == libvlc_Stopped))
{
Stop();
return;
}
// Reset playback to start if video is looped.
if (_looped && (state == libvlc_Stopping || state == libvlc_Stopped))
libvlc_media_player_play(_player);
HandleError();
}
void VideoHandler::RenderBackground()
{
_texture.Width = _size.x;
_texture.Height = _size.y;
_texture.Texture = _videoTexture;
_texture.ShaderResourceView = _textureView;
g_Renderer.UpdateVideoTexture(&_texture);
}
bool VideoHandler::HandleError()
{
if (_vlcInstance == nullptr)
return false;
const char* vlcMsg = libvlc_errmsg();
if (vlcMsg && strlen(vlcMsg) > 0)
{
TENLog("Video player error: " + std::string(vlcMsg), LogLevel::Error);
return false;
}
return true;
}
bool VideoHandler::InitializeD3DTexture()
{
if (_videoTexture != nullptr || _textureView != nullptr)
{
TENLog("Video texture already exists", LogLevel::Error);
return false;
}
_frameBuffer.resize(_size.x * _size.y * 4);
auto texDesc = D3D11_TEXTURE2D_DESC{};
texDesc.Width = _size.x;
texDesc.Height = _size.y;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
texDesc.SampleDesc.Count = 1;
texDesc.Usage = D3D11_USAGE_DYNAMIC;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
texDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
texDesc.MiscFlags = 0;
if (FAILED(_d3dDevice->CreateTexture2D(&texDesc, nullptr, &_videoTexture)))
{
TENLog("Failed to create video texture", LogLevel::Error);
return false;
}
if (_videoTexture != nullptr && FAILED(_d3dDevice->CreateShaderResourceView(_videoTexture, nullptr, &_textureView)))
{
TENLog("Failed to create shader resource view", LogLevel::Error);
return false;
}
return true;
}
void VideoHandler::DeinitializeD3DTexture()
{
if (_videoTexture != nullptr)
{
_videoTexture->Release();
_videoTexture = nullptr;
}
if (_textureView != nullptr)
{
_textureView->Release();
_textureView = nullptr;
}
_texture = {};
_frameBuffer.clear();
_size = Vector2i::Zero;
}
void VideoHandler::DeinitializePlayer()
{
if (_deInitializing || _player == nullptr)
return;
DeinitializeD3DTexture();
libvlc_media_player_stop_async(_player);
libvlc_media_player_release(_player);
_player = nullptr;
_fileName = {};
HandleError();
}
void* VideoHandler::OnLockFrame(void* data, void** pixels)
{
auto* player = static_cast<VideoHandler*>(data);
*pixels = player->_frameBuffer.data();
return nullptr;
}
void VideoHandler::OnUnlockFrame(void* data, void* picture, void* const* pixels)
{
auto* player = static_cast<VideoHandler*>(data);
player->_needRender = true;
if (player->_playbackMode == VideoPlaybackMode::Exclusive)
player->_updateInput = true;
}
void VideoHandler::OnLog(void* data, int level, const libvlc_log_t* ctx, const char* fmt, va_list args)
{
LogLevel logLevel = LogLevel::Info;
switch (level)
{
case LIBVLC_ERROR:
logLevel = LogLevel::Error;
break;
case LIBVLC_WARNING:
logLevel = LogLevel::Warning;
break;
case LIBVLC_NOTICE:
logLevel = LogLevel::Info;
break;
case LIBVLC_DEBUG:
logLevel = LogLevel::Info;
break;
default:
logLevel = LogLevel::Info;
break;
}
char logMgs[1024];
vsnprintf(logMgs, sizeof(logMgs), fmt, args);
TENLog("VLC: " + std::string(logMgs), logLevel);
}
unsigned int VideoHandler::OnSetup(void** data, char* chroma, unsigned* width, unsigned* height, unsigned* pitches, unsigned* lines)
{
strncpy(chroma, "BGRA", 4);
*pitches = *width * 4;
*lines = *height;
auto* player = static_cast<VideoHandler*>(*data);
// Fetch video size only once when playback is just started.
if (player->_size == Vector2i::Zero)
{
player->_size = Vector2i(*width, *height);
player->InitializeD3DTexture();
}
return 1;
}
}

View file

@ -0,0 +1,107 @@
#pragma once
#include "Renderer/Graphics/Texture2D.h"
using namespace TEN::Math;
using namespace TEN::Renderer::Graphics;
namespace TEN::Video
{
enum class VideoPlaybackMode
{
Exclusive,
Background
};
class VideoHandler
{
private:
// VLC core components
libvlc_instance_t* _vlcInstance = nullptr;
libvlc_media_player_t* _player = nullptr;
// Video properties
int _volume = 100;
bool _silent = false;
bool _looped = false;
VideoPlaybackMode _playbackMode = VideoPlaybackMode::Exclusive;
Vector2i _size = Vector2i::Zero;
std::string _fileName = {};
std::string _videoDirectory = {};
// Render synchronization
bool _needRender = false;
bool _updateInput = false;
bool _deInitializing = false;
// Renderer Resources
std::vector<char> _frameBuffer = {};
Texture2D _texture = {};
ID3D11Texture2D* _videoTexture = nullptr;
ID3D11Device* _d3dDevice = nullptr;
ID3D11DeviceContext* _d3dContext = nullptr;
ID3D11ShaderResourceView* _textureView = nullptr;
public:
// Constructors
VideoHandler() = default;
// Getters
int GetPosition() const;
float GetNormalizedPosition() const;
std::string GetFileName() const;
Color GetDominantColor() const;
bool GetSilent() const;
bool GetLooped() const;
// Setters
void SetPosition(int frameCount);
void SetNormalizedPosition(float pos);
void SetVolume(int volume);
// Inquirers
bool IsPlaying() const;
// Utilties
void Initialize(const std::string& gameDir, ID3D11Device* device, ID3D11DeviceContext* context);
void DeInitialize();
bool Play(const std::string& filename, VideoPlaybackMode mode = VideoPlaybackMode::Exclusive, bool silent = false, bool looped = false);
bool Pause();
bool Resume();
void Stop();
bool Update();
private:
// Update
void UpdateExclusive();
void RenderExclusive();
void UpdateBackground();
void RenderBackground();
// Helpers
bool HandleError();
bool InitializeD3DTexture();
void DeinitializeD3DTexture();
void DeinitializePlayer();
// VLC callbacks
static void* OnLockFrame(void* data, void** pixels);
static void OnUnlockFrame(void* data, void* picture, void* const* pixels);
static void OnLog(void* data, int level, const libvlc_log_t* ctx, const char* fmt, va_list args);
static unsigned int OnSetup(void** data, char* chroma, unsigned* width, unsigned* height, unsigned* pitches, unsigned* lines);
};
extern VideoHandler g_VideoPlayer;
}

View file

@ -1065,11 +1065,13 @@ void LoadAnimatedTextures()
for (int i = 0; i < animatedTextureCount; i++) for (int i = 0; i < animatedTextureCount; i++)
{ {
auto sequence = ANIMATED_TEXTURES_SEQUENCE{}; auto sequence = ANIMATED_TEXTURES_SEQUENCE{};
sequence.atlas = ReadInt32(); sequence.Atlas = ReadInt32();
sequence.Fps = ReadInt32(); sequence.Fps = ReadUInt8();
sequence.numFrames = ReadCount(); sequence.Type = ReadUInt8();
ReadUInt16(); // Unused.
sequence.NumFrames = ReadCount();
for (int j = 0; j < sequence.numFrames; j++) for (int j = 0; j < sequence.NumFrames; j++)
{ {
auto frame = ANIMATED_TEXTURES_FRAME{}; auto frame = ANIMATED_TEXTURES_FRAME{};
frame.x1 = ReadFloat(); frame.x1 = ReadFloat();
@ -1080,7 +1082,7 @@ void LoadAnimatedTextures()
frame.y3 = ReadFloat(); frame.y3 = ReadFloat();
frame.x4 = ReadFloat(); frame.x4 = ReadFloat();
frame.y4 = ReadFloat(); frame.y4 = ReadFloat();
sequence.frames.push_back(frame); sequence.Frames.push_back(frame);
} }
g_Level.AnimatedTexturesSequences.push_back(sequence); g_Level.AnimatedTexturesSequences.push_back(sequence);

View file

@ -43,10 +43,11 @@ struct ANIMATED_TEXTURES_FRAME
struct ANIMATED_TEXTURES_SEQUENCE struct ANIMATED_TEXTURES_SEQUENCE
{ {
int atlas; int Type;
int Atlas;
int Fps; int Fps;
int numFrames; int NumFrames;
std::vector<ANIMATED_TEXTURES_FRAME> frames; std::vector<ANIMATED_TEXTURES_FRAME> Frames;
}; };
struct AI_OBJECT struct AI_OBJECT

View file

@ -137,6 +137,10 @@ struct Soundtrack;
struct SoundtrackBuilder; struct SoundtrackBuilder;
struct SoundtrackT; struct SoundtrackT;
struct VideoInfo;
struct VideoInfoBuilder;
struct VideoInfoT;
struct SwarmObjectInfo; struct SwarmObjectInfo;
struct SwarmObjectInfoBuilder; struct SwarmObjectInfoBuilder;
struct SwarmObjectInfoT; struct SwarmObjectInfoT;
@ -5954,6 +5958,113 @@ inline flatbuffers::Offset<Soundtrack> CreateSoundtrackDirect(
flatbuffers::Offset<Soundtrack> CreateSoundtrack(flatbuffers::FlatBufferBuilder &_fbb, const SoundtrackT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); flatbuffers::Offset<Soundtrack> CreateSoundtrack(flatbuffers::FlatBufferBuilder &_fbb, const SoundtrackT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
struct VideoInfoT : public flatbuffers::NativeTable {
typedef VideoInfo TableType;
std::string name{};
float position = 0.0f;
bool silent = false;
bool looped = false;
};
struct VideoInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef VideoInfoT NativeTableType;
typedef VideoInfoBuilder Builder;
struct Traits;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_POSITION = 6,
VT_SILENT = 8,
VT_LOOPED = 10
};
const flatbuffers::String *name() const {
return GetPointer<const flatbuffers::String *>(VT_NAME);
}
float position() const {
return GetField<float>(VT_POSITION, 0.0f);
}
bool silent() const {
return GetField<uint8_t>(VT_SILENT, 0) != 0;
}
bool looped() const {
return GetField<uint8_t>(VT_LOOPED, 0) != 0;
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyOffset(verifier, VT_NAME) &&
verifier.VerifyString(name()) &&
VerifyField<float>(verifier, VT_POSITION) &&
VerifyField<uint8_t>(verifier, VT_SILENT) &&
VerifyField<uint8_t>(verifier, VT_LOOPED) &&
verifier.EndTable();
}
VideoInfoT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(VideoInfoT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<VideoInfo> Pack(flatbuffers::FlatBufferBuilder &_fbb, const VideoInfoT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct VideoInfoBuilder {
typedef VideoInfo Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(VideoInfo::VT_NAME, name);
}
void add_position(float position) {
fbb_.AddElement<float>(VideoInfo::VT_POSITION, position, 0.0f);
}
void add_silent(bool silent) {
fbb_.AddElement<uint8_t>(VideoInfo::VT_SILENT, static_cast<uint8_t>(silent), 0);
}
void add_looped(bool looped) {
fbb_.AddElement<uint8_t>(VideoInfo::VT_LOOPED, static_cast<uint8_t>(looped), 0);
}
explicit VideoInfoBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
flatbuffers::Offset<VideoInfo> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<VideoInfo>(end);
return o;
}
};
inline flatbuffers::Offset<VideoInfo> CreateVideoInfo(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
float position = 0.0f,
bool silent = false,
bool looped = false) {
VideoInfoBuilder builder_(_fbb);
builder_.add_position(position);
builder_.add_name(name);
builder_.add_looped(looped);
builder_.add_silent(silent);
return builder_.Finish();
}
struct VideoInfo::Traits {
using type = VideoInfo;
static auto constexpr Create = CreateVideoInfo;
};
inline flatbuffers::Offset<VideoInfo> CreateVideoInfoDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
float position = 0.0f,
bool silent = false,
bool looped = false) {
auto name__ = name ? _fbb.CreateString(name) : 0;
return TEN::Save::CreateVideoInfo(
_fbb,
name__,
position,
silent,
looped);
}
flatbuffers::Offset<VideoInfo> CreateVideoInfo(flatbuffers::FlatBufferBuilder &_fbb, const VideoInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
struct SwarmObjectInfoT : public flatbuffers::NativeTable { struct SwarmObjectInfoT : public flatbuffers::NativeTable {
typedef SwarmObjectInfo TableType; typedef SwarmObjectInfo TableType;
bool on = false; bool on = false;
@ -6888,7 +6999,7 @@ struct FireflyDataT : public flatbuffers::NativeTable {
int32_t b = 0; int32_t b = 0;
bool on = false; bool on = false;
float size = 0.0f; float size = 0.0f;
int32_t rot_Ang = 0; int32_t rot_ang = 0;
}; };
struct FireflyData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { struct FireflyData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@ -6982,7 +7093,7 @@ struct FireflyData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
float size() const { float size() const {
return GetField<float>(VT_SIZE, 0.0f); return GetField<float>(VT_SIZE, 0.0f);
} }
int32_t rot_Ang() const { int32_t rot_ang() const {
return GetField<int32_t>(VT_ROT_ANG, 0); return GetField<int32_t>(VT_ROT_ANG, 0);
} }
bool Verify(flatbuffers::Verifier &verifier) const { bool Verify(flatbuffers::Verifier &verifier) const {
@ -7083,8 +7194,8 @@ struct FireflyDataBuilder {
void add_size(float size) { void add_size(float size) {
fbb_.AddElement<float>(FireflyData::VT_SIZE, size, 0.0f); fbb_.AddElement<float>(FireflyData::VT_SIZE, size, 0.0f);
} }
void add_rot_Ang(int32_t rot_Ang) { void add_rot_ang(int32_t rot_ang) {
fbb_.AddElement<int32_t>(FireflyData::VT_ROT_ANG, rot_Ang, 0); fbb_.AddElement<int32_t>(FireflyData::VT_ROT_ANG, rot_ang, 0);
} }
explicit FireflyDataBuilder(flatbuffers::FlatBufferBuilder &_fbb) explicit FireflyDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) { : fbb_(_fbb) {
@ -7120,9 +7231,9 @@ inline flatbuffers::Offset<FireflyData> CreateFireflyData(
int32_t b = 0, int32_t b = 0,
bool on = false, bool on = false,
float size = 0.0f, float size = 0.0f,
int32_t rot_Ang = 0) { int32_t rot_ang = 0) {
FireflyDataBuilder builder_(_fbb); FireflyDataBuilder builder_(_fbb);
builder_.add_rot_Ang(rot_Ang); builder_.add_rot_ang(rot_ang);
builder_.add_size(size); builder_.add_size(size);
builder_.add_b(b); builder_.add_b(b);
builder_.add_g(g); builder_.add_g(g);
@ -8316,6 +8427,7 @@ struct SaveGameT : public flatbuffers::NativeTable {
std::vector<int32_t> action_queue{}; std::vector<int32_t> action_queue{};
std::vector<std::unique_ptr<TEN::Save::SoundtrackT>> soundtracks{}; std::vector<std::unique_ptr<TEN::Save::SoundtrackT>> soundtracks{};
std::vector<int32_t> cd_flags{}; std::vector<int32_t> cd_flags{};
std::unique_ptr<TEN::Save::VideoInfoT> video{};
int32_t postprocess_mode = 0; int32_t postprocess_mode = 0;
float postprocess_strength = 0.0f; float postprocess_strength = 0.0f;
std::unique_ptr<TEN::Save::Vector3> postprocess_tint{}; std::unique_ptr<TEN::Save::Vector3> postprocess_tint{};
@ -8383,30 +8495,31 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_ACTION_QUEUE = 70, VT_ACTION_QUEUE = 70,
VT_SOUNDTRACKS = 72, VT_SOUNDTRACKS = 72,
VT_CD_FLAGS = 74, VT_CD_FLAGS = 74,
VT_POSTPROCESS_MODE = 76, VT_VIDEO = 76,
VT_POSTPROCESS_STRENGTH = 78, VT_POSTPROCESS_MODE = 78,
VT_POSTPROCESS_TINT = 80, VT_POSTPROCESS_STRENGTH = 80,
VT_ROPE = 82, VT_POSTPROCESS_TINT = 82,
VT_PENDULUM = 84, VT_ROPE = 84,
VT_ALTERNATE_PENDULUM = 86, VT_PENDULUM = 86,
VT_VOLUMES = 88, VT_ALTERNATE_PENDULUM = 88,
VT_GLOBAL_EVENT_SETS = 90, VT_VOLUMES = 90,
VT_VOLUME_EVENT_SETS = 92, VT_GLOBAL_EVENT_SETS = 92,
VT_SCRIPT_VARS = 94, VT_VOLUME_EVENT_SETS = 94,
VT_CALLBACKS_PRE_START = 96, VT_SCRIPT_VARS = 96,
VT_CALLBACKS_POST_START = 98, VT_CALLBACKS_PRE_START = 98,
VT_CALLBACKS_PRE_END = 100, VT_CALLBACKS_POST_START = 100,
VT_CALLBACKS_POST_END = 102, VT_CALLBACKS_PRE_END = 102,
VT_CALLBACKS_PRE_SAVE = 104, VT_CALLBACKS_POST_END = 104,
VT_CALLBACKS_POST_SAVE = 106, VT_CALLBACKS_PRE_SAVE = 106,
VT_CALLBACKS_PRE_LOAD = 108, VT_CALLBACKS_POST_SAVE = 108,
VT_CALLBACKS_POST_LOAD = 110, VT_CALLBACKS_PRE_LOAD = 110,
VT_CALLBACKS_PRE_LOOP = 112, VT_CALLBACKS_POST_LOAD = 112,
VT_CALLBACKS_POST_LOOP = 114, VT_CALLBACKS_PRE_LOOP = 114,
VT_CALLBACKS_PRE_USEITEM = 116, VT_CALLBACKS_POST_LOOP = 116,
VT_CALLBACKS_POST_USEITEM = 118, VT_CALLBACKS_PRE_USEITEM = 118,
VT_CALLBACKS_PRE_FREEZE = 120, VT_CALLBACKS_POST_USEITEM = 120,
VT_CALLBACKS_POST_FREEZE = 122 VT_CALLBACKS_PRE_FREEZE = 122,
VT_CALLBACKS_POST_FREEZE = 124
}; };
const TEN::Save::SaveGameHeader *header() const { const TEN::Save::SaveGameHeader *header() const {
return GetPointer<const TEN::Save::SaveGameHeader *>(VT_HEADER); return GetPointer<const TEN::Save::SaveGameHeader *>(VT_HEADER);
@ -8516,6 +8629,9 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const flatbuffers::Vector<int32_t> *cd_flags() const { const flatbuffers::Vector<int32_t> *cd_flags() const {
return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_CD_FLAGS); return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_CD_FLAGS);
} }
const TEN::Save::VideoInfo *video() const {
return GetPointer<const TEN::Save::VideoInfo *>(VT_VIDEO);
}
int32_t postprocess_mode() const { int32_t postprocess_mode() const {
return GetField<int32_t>(VT_POSTPROCESS_MODE, 0); return GetField<int32_t>(VT_POSTPROCESS_MODE, 0);
} }
@ -8667,6 +8783,8 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
verifier.VerifyVectorOfTables(soundtracks()) && verifier.VerifyVectorOfTables(soundtracks()) &&
VerifyOffset(verifier, VT_CD_FLAGS) && VerifyOffset(verifier, VT_CD_FLAGS) &&
verifier.VerifyVector(cd_flags()) && verifier.VerifyVector(cd_flags()) &&
VerifyOffset(verifier, VT_VIDEO) &&
verifier.VerifyTable(video()) &&
VerifyField<int32_t>(verifier, VT_POSTPROCESS_MODE) && VerifyField<int32_t>(verifier, VT_POSTPROCESS_MODE) &&
VerifyField<float>(verifier, VT_POSTPROCESS_STRENGTH) && VerifyField<float>(verifier, VT_POSTPROCESS_STRENGTH) &&
VerifyField<TEN::Save::Vector3>(verifier, VT_POSTPROCESS_TINT) && VerifyField<TEN::Save::Vector3>(verifier, VT_POSTPROCESS_TINT) &&
@ -8848,6 +8966,9 @@ struct SaveGameBuilder {
void add_cd_flags(flatbuffers::Offset<flatbuffers::Vector<int32_t>> cd_flags) { void add_cd_flags(flatbuffers::Offset<flatbuffers::Vector<int32_t>> cd_flags) {
fbb_.AddOffset(SaveGame::VT_CD_FLAGS, cd_flags); fbb_.AddOffset(SaveGame::VT_CD_FLAGS, cd_flags);
} }
void add_video(flatbuffers::Offset<TEN::Save::VideoInfo> video) {
fbb_.AddOffset(SaveGame::VT_VIDEO, video);
}
void add_postprocess_mode(int32_t postprocess_mode) { void add_postprocess_mode(int32_t postprocess_mode) {
fbb_.AddElement<int32_t>(SaveGame::VT_POSTPROCESS_MODE, postprocess_mode, 0); fbb_.AddElement<int32_t>(SaveGame::VT_POSTPROCESS_MODE, postprocess_mode, 0);
} }
@ -8969,6 +9090,7 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGame(
flatbuffers::Offset<flatbuffers::Vector<int32_t>> action_queue = 0, flatbuffers::Offset<flatbuffers::Vector<int32_t>> action_queue = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TEN::Save::Soundtrack>>> soundtracks = 0, flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TEN::Save::Soundtrack>>> soundtracks = 0,
flatbuffers::Offset<flatbuffers::Vector<int32_t>> cd_flags = 0, flatbuffers::Offset<flatbuffers::Vector<int32_t>> cd_flags = 0,
flatbuffers::Offset<TEN::Save::VideoInfo> video = 0,
int32_t postprocess_mode = 0, int32_t postprocess_mode = 0,
float postprocess_strength = 0.0f, float postprocess_strength = 0.0f,
const TEN::Save::Vector3 *postprocess_tint = 0, const TEN::Save::Vector3 *postprocess_tint = 0,
@ -9018,6 +9140,7 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGame(
builder_.add_postprocess_tint(postprocess_tint); builder_.add_postprocess_tint(postprocess_tint);
builder_.add_postprocess_strength(postprocess_strength); builder_.add_postprocess_strength(postprocess_strength);
builder_.add_postprocess_mode(postprocess_mode); builder_.add_postprocess_mode(postprocess_mode);
builder_.add_video(video);
builder_.add_cd_flags(cd_flags); builder_.add_cd_flags(cd_flags);
builder_.add_soundtracks(soundtracks); builder_.add_soundtracks(soundtracks);
builder_.add_action_queue(action_queue); builder_.add_action_queue(action_queue);
@ -9100,6 +9223,7 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGameDirect(
const std::vector<int32_t> *action_queue = nullptr, const std::vector<int32_t> *action_queue = nullptr,
const std::vector<flatbuffers::Offset<TEN::Save::Soundtrack>> *soundtracks = nullptr, const std::vector<flatbuffers::Offset<TEN::Save::Soundtrack>> *soundtracks = nullptr,
const std::vector<int32_t> *cd_flags = nullptr, const std::vector<int32_t> *cd_flags = nullptr,
flatbuffers::Offset<TEN::Save::VideoInfo> video = 0,
int32_t postprocess_mode = 0, int32_t postprocess_mode = 0,
float postprocess_strength = 0.0f, float postprocess_strength = 0.0f,
const TEN::Save::Vector3 *postprocess_tint = 0, const TEN::Save::Vector3 *postprocess_tint = 0,
@ -9199,6 +9323,7 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGameDirect(
action_queue__, action_queue__,
soundtracks__, soundtracks__,
cd_flags__, cd_flags__,
video,
postprocess_mode, postprocess_mode,
postprocess_strength, postprocess_strength,
postprocess_tint, postprocess_tint,
@ -10885,6 +11010,41 @@ inline flatbuffers::Offset<Soundtrack> CreateSoundtrack(flatbuffers::FlatBufferB
_position); _position);
} }
inline VideoInfoT *VideoInfo::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<VideoInfoT>();
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void VideoInfo::UnPackTo(VideoInfoT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = name(); if (_e) _o->name = _e->str(); }
{ auto _e = position(); _o->position = _e; }
{ auto _e = silent(); _o->silent = _e; }
{ auto _e = looped(); _o->looped = _e; }
}
inline flatbuffers::Offset<VideoInfo> VideoInfo::Pack(flatbuffers::FlatBufferBuilder &_fbb, const VideoInfoT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
return CreateVideoInfo(_fbb, _o, _rehasher);
}
inline flatbuffers::Offset<VideoInfo> CreateVideoInfo(flatbuffers::FlatBufferBuilder &_fbb, const VideoInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const VideoInfoT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _name = _o->name.empty() ? _fbb.CreateSharedString("") : _fbb.CreateString(_o->name);
auto _position = _o->position;
auto _silent = _o->silent;
auto _looped = _o->looped;
return TEN::Save::CreateVideoInfo(
_fbb,
_name,
_position,
_silent,
_looped);
}
inline SwarmObjectInfoT *SwarmObjectInfo::UnPack(const flatbuffers::resolver_function_t *_resolver) const { inline SwarmObjectInfoT *SwarmObjectInfo::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<SwarmObjectInfoT>(); auto _o = std::make_unique<SwarmObjectInfoT>();
UnPackTo(_o.get(), _resolver); UnPackTo(_o.get(), _resolver);
@ -11228,7 +11388,7 @@ inline void FireflyData::UnPackTo(FireflyDataT *_o, const flatbuffers::resolver_
{ auto _e = b(); _o->b = _e; } { auto _e = b(); _o->b = _e; }
{ auto _e = on(); _o->on = _e; } { auto _e = on(); _o->on = _e; }
{ auto _e = size(); _o->size = _e; } { auto _e = size(); _o->size = _e; }
{ auto _e = rot_Ang(); _o->rot_Ang = _e; } { auto _e = rot_ang(); _o->rot_ang = _e; }
} }
inline flatbuffers::Offset<FireflyData> FireflyData::Pack(flatbuffers::FlatBufferBuilder &_fbb, const FireflyDataT* _o, const flatbuffers::rehasher_function_t *_rehasher) { inline flatbuffers::Offset<FireflyData> FireflyData::Pack(flatbuffers::FlatBufferBuilder &_fbb, const FireflyDataT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@ -11260,7 +11420,7 @@ inline flatbuffers::Offset<FireflyData> CreateFireflyData(flatbuffers::FlatBuffe
auto _b = _o->b; auto _b = _o->b;
auto _on = _o->on; auto _on = _o->on;
auto _size = _o->size; auto _size = _o->size;
auto _rot_Ang = _o->rot_Ang; auto _rot_ang = _o->rot_ang;
return TEN::Save::CreateFireflyData( return TEN::Save::CreateFireflyData(
_fbb, _fbb,
_sprite_index, _sprite_index,
@ -11284,7 +11444,7 @@ inline flatbuffers::Offset<FireflyData> CreateFireflyData(flatbuffers::FlatBuffe
_b, _b,
_on, _on,
_size, _size,
_rot_Ang); _rot_ang);
} }
inline ScriptTableT *ScriptTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const { inline ScriptTableT *ScriptTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
@ -11744,6 +11904,7 @@ inline void SaveGame::UnPackTo(SaveGameT *_o, const flatbuffers::resolver_functi
{ auto _e = action_queue(); if (_e) { _o->action_queue.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->action_queue[_i] = _e->Get(_i); } } } { auto _e = action_queue(); if (_e) { _o->action_queue.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->action_queue[_i] = _e->Get(_i); } } }
{ auto _e = soundtracks(); if (_e) { _o->soundtracks.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->soundtracks[_i] = std::unique_ptr<TEN::Save::SoundtrackT>(_e->Get(_i)->UnPack(_resolver)); } } } { auto _e = soundtracks(); if (_e) { _o->soundtracks.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->soundtracks[_i] = std::unique_ptr<TEN::Save::SoundtrackT>(_e->Get(_i)->UnPack(_resolver)); } } }
{ auto _e = cd_flags(); if (_e) { _o->cd_flags.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->cd_flags[_i] = _e->Get(_i); } } } { auto _e = cd_flags(); if (_e) { _o->cd_flags.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->cd_flags[_i] = _e->Get(_i); } } }
{ auto _e = video(); if (_e) _o->video = std::unique_ptr<TEN::Save::VideoInfoT>(_e->UnPack(_resolver)); }
{ auto _e = postprocess_mode(); _o->postprocess_mode = _e; } { auto _e = postprocess_mode(); _o->postprocess_mode = _e; }
{ auto _e = postprocess_strength(); _o->postprocess_strength = _e; } { auto _e = postprocess_strength(); _o->postprocess_strength = _e; }
{ auto _e = postprocess_tint(); if (_e) _o->postprocess_tint = std::unique_ptr<TEN::Save::Vector3>(new TEN::Save::Vector3(*_e)); } { auto _e = postprocess_tint(); if (_e) _o->postprocess_tint = std::unique_ptr<TEN::Save::Vector3>(new TEN::Save::Vector3(*_e)); }
@ -11814,6 +11975,7 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGame(flatbuffers::FlatBufferBuild
auto _action_queue = _fbb.CreateVector(_o->action_queue); auto _action_queue = _fbb.CreateVector(_o->action_queue);
auto _soundtracks = _fbb.CreateVector<flatbuffers::Offset<TEN::Save::Soundtrack>> (_o->soundtracks.size(), [](size_t i, _VectorArgs *__va) { return CreateSoundtrack(*__va->__fbb, __va->__o->soundtracks[i].get(), __va->__rehasher); }, &_va ); auto _soundtracks = _fbb.CreateVector<flatbuffers::Offset<TEN::Save::Soundtrack>> (_o->soundtracks.size(), [](size_t i, _VectorArgs *__va) { return CreateSoundtrack(*__va->__fbb, __va->__o->soundtracks[i].get(), __va->__rehasher); }, &_va );
auto _cd_flags = _fbb.CreateVector(_o->cd_flags); auto _cd_flags = _fbb.CreateVector(_o->cd_flags);
auto _video = _o->video ? CreateVideoInfo(_fbb, _o->video.get(), _rehasher) : 0;
auto _postprocess_mode = _o->postprocess_mode; auto _postprocess_mode = _o->postprocess_mode;
auto _postprocess_strength = _o->postprocess_strength; auto _postprocess_strength = _o->postprocess_strength;
auto _postprocess_tint = _o->postprocess_tint ? _o->postprocess_tint.get() : 0; auto _postprocess_tint = _o->postprocess_tint ? _o->postprocess_tint.get() : 0;
@ -11876,6 +12038,7 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGame(flatbuffers::FlatBufferBuild
_action_queue, _action_queue,
_soundtracks, _soundtracks,
_cd_flags, _cd_flags,
_video,
_postprocess_mode, _postprocess_mode,
_postprocess_strength, _postprocess_strength,
_postprocess_tint, _postprocess_tint,

View file

@ -432,6 +432,13 @@ table Soundtrack {
position: uint64; position: uint64;
} }
table VideoInfo {
name: string;
position: float;
silent: bool;
looped: bool;
}
table SwarmObjectInfo { table SwarmObjectInfo {
on: bool; on: bool;
pose: Pose; pose: Pose;
@ -521,7 +528,7 @@ table FireflyData {
b: int32; b: int32;
on: bool; on: bool;
size: float; size: float;
rot_Ang: int32; rot_ang: int32;
} }
struct KeyValPair { struct KeyValPair {
@ -650,6 +657,7 @@ table SaveGame {
action_queue: [int32]; action_queue: [int32];
soundtracks: [Soundtrack]; soundtracks: [Soundtrack];
cd_flags: [int32]; cd_flags: [int32];
video: VideoInfo;
postprocess_mode: int32; postprocess_mode: int32;
postprocess_strength: float; postprocess_strength: float;

View file

@ -19,11 +19,12 @@
#include "Scripting/Internal/LanguageScript.h" #include "Scripting/Internal/LanguageScript.h"
#include "Scripting/Include/ScriptInterfaceState.h" #include "Scripting/Include/ScriptInterfaceState.h"
#include "Scripting/Include/ScriptInterfaceLevel.h" #include "Scripting/Include/ScriptInterfaceLevel.h"
#include "Video/Video.h"
using namespace TEN::Renderer; using namespace TEN::Renderer;
using namespace TEN::Input; using namespace TEN::Input;
using namespace TEN::Utils; using namespace TEN::Utils;
using namespace TEN::Video;
WINAPP App; WINAPP App;
unsigned int ThreadID, ConsoleThreadID; unsigned int ThreadID, ConsoleThreadID;
@ -354,8 +355,11 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
if (!DebugMode && ThreadHandle > 0) if (!DebugMode && ThreadHandle > 0)
{ {
TENLog("Resuming game thread", LogLevel::Info); TENLog("Resuming game thread", LogLevel::Info);
ResumeThread((HANDLE)ThreadHandle);
if (!g_VideoPlayer.Resume())
ResumeAllSounds(SoundPauseMode::Global); ResumeAllSounds(SoundPauseMode::Global);
ResumeThread((HANDLE)ThreadHandle);
} }
return 0; return 0;
@ -369,8 +373,11 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
if (!DebugMode) if (!DebugMode)
{ {
TENLog("Suspending game thread", LogLevel::Info); TENLog("Suspending game thread", LogLevel::Info);
SuspendThread((HANDLE)ThreadHandle);
if (!g_VideoPlayer.Pause())
PauseAllSounds(SoundPauseMode::Global); PauseAllSounds(SoundPauseMode::Global);
SuspendThread((HANDLE)ThreadHandle);
} }
} }
@ -592,7 +599,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
CoInitializeEx(NULL, COINIT_MULTITHREADED); CoInitializeEx(NULL, COINIT_MULTITHREADED);
// Initialize renderer. // Initialize renderer.
g_Renderer.Initialize(g_Configuration.ScreenWidth, g_Configuration.ScreenHeight, g_Configuration.EnableWindowedMode, App.WindowHandle); g_Renderer.Initialize(gameDir, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight, g_Configuration.EnableWindowedMode, App.WindowHandle);
// Initialize audio. // Initialize audio.
Sound_Init(gameDir); Sound_Init(gameDir);
@ -646,25 +653,7 @@ void WinClose()
CloseHandle((HANDLE)ConsoleThreadHandle); CloseHandle((HANDLE)ConsoleThreadHandle);
WaitForSingleObject((HANDLE)ThreadHandle, 5000); WaitForSingleObject((HANDLE)ThreadHandle, 5000);
DestroyAcceleratorTable(hAccTable); DestroyAcceleratorTable(hAccTable);
Sound_DeInit();
DeinitializeInput();
delete g_GameScript;
g_GameScript = nullptr;
delete g_GameFlow;
g_GameFlow = nullptr;
delete g_GameScriptEntities;
g_GameScriptEntities = nullptr;
delete g_GameStringsHandler;
g_GameStringsHandler = nullptr;
ShutdownTENLog(); ShutdownTENLog();
CoUninitialize(); CoUninitialize();
} }

View file

@ -73,14 +73,14 @@
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)Build\$(Configuration)\Bin\x86\</OutDir> <OutDir>$(SolutionDir)Build\$(Configuration)\Bin\x86\</OutDir>
<ExecutablePath>$(ExecutablePath);$(DXSDK_DIR)Utilities\bin\x86</ExecutablePath> <ExecutablePath>$(ExecutablePath);$(DXSDK_DIR)Utilities\bin\x86</ExecutablePath>
<IncludePath>$(SolutionDir)Libs;$(SolutionDir)Libs\lua;$(SolutionDir)Libs\sol;$(SolutionDir)Libs\zlib;$(SolutionDir)Libs\spdlog;$(SolutionDir)Libs\ois;$(SolutionDir)Libs\bass;$(SolutionDir)Libs\srtparser;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)Libs;$(SolutionDir)Libs\lua;$(SolutionDir)Libs\sol;$(SolutionDir)Libs\zlib;$(SolutionDir)Libs\spdlog;$(SolutionDir)Libs\ois;$(SolutionDir)Libs\vlc;$(SolutionDir)Libs\bass;$(SolutionDir)Libs\srtparser;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\x86;$(SolutionDir)Libs\spdlog\x86;$(SolutionDir)Libs\lua\x86;$(SolutionDir)Libs\zlib\x86;$(SolutionDir)Libs\bass\x86;$(SolutionDir)Libs\ois\x86</LibraryPath> <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\x86;$(SolutionDir)Libs\spdlog\x86;$(SolutionDir)Libs\lua\x86;$(SolutionDir)Libs\zlib\x86;$(SolutionDir)Libs\vlc\x86;$(SolutionDir)Libs\bass\x86;$(SolutionDir)Libs\ois\x86</LibraryPath>
<TargetExt>.exe</TargetExt> <TargetExt>.exe</TargetExt>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ExecutablePath>$(ExecutablePath);$(DXSDK_DIR)Utilities\bin\x64</ExecutablePath> <ExecutablePath>$(ExecutablePath);$(DXSDK_DIR)Utilities\bin\x64</ExecutablePath>
<IncludePath>$(SolutionDir)Libs;$(SolutionDir)Libs\lua;$(SolutionDir)Libs\sol;$(SolutionDir)Libs\zlib;$(SolutionDir)Libs\spdlog;$(SolutionDir)Libs\ois;$(SolutionDir)Libs\bass;$(SolutionDir)Libs\srtparser;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)Libs;$(SolutionDir)Libs\lua;$(SolutionDir)Libs\sol;$(SolutionDir)Libs\zlib;$(SolutionDir)Libs\spdlog;$(SolutionDir)Libs\ois;$(SolutionDir)Libs\vlc;$(SolutionDir)Libs\bass;$(SolutionDir)Libs\srtparser;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\x64;$(SolutionDir)Libs\spdlog\x64;$(SolutionDir)Libs\lua\x64;$(SolutionDir)Libs\zlib\x64;$(SolutionDir)Libs\bass\x64;$(SolutionDir)Libs\ois\x64</LibraryPath> <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\x64;$(SolutionDir)Libs\spdlog\x64;$(SolutionDir)Libs\lua\x64;$(SolutionDir)Libs\zlib\x64;$(SolutionDir)Libs\vlc\x64;$(SolutionDir)Libs\bass\x64;$(SolutionDir)Libs\ois\x64</LibraryPath>
<TargetExt>.exe</TargetExt> <TargetExt>.exe</TargetExt>
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
<TargetName>$(ProjectName)</TargetName> <TargetName>$(ProjectName)</TargetName>
@ -91,14 +91,14 @@
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)Build\$(Configuration)\Bin\x86\</OutDir> <OutDir>$(SolutionDir)Build\$(Configuration)\Bin\x86\</OutDir>
<ExecutablePath>$(ExecutablePath);$(DXSDK_DIR)Utilities\bin\x86</ExecutablePath> <ExecutablePath>$(ExecutablePath);$(DXSDK_DIR)Utilities\bin\x86</ExecutablePath>
<IncludePath>$(SolutionDir)Libs;$(SolutionDir)Libs\lua;$(SolutionDir)Libs\sol;$(SolutionDir)Libs\zlib;$(SolutionDir)Libs\spdlog;$(SolutionDir)Libs\ois;$(SolutionDir)Libs\bass;$(SolutionDir)Libs\srtparser;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)Libs;$(SolutionDir)Libs\lua;$(SolutionDir)Libs\sol;$(SolutionDir)Libs\zlib;$(SolutionDir)Libs\spdlog;$(SolutionDir)Libs\ois;$(SolutionDir)Libs\vlc;$(SolutionDir)Libs\bass;$(SolutionDir)Libs\srtparser;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\x86;$(SolutionDir)Libs\spdlog\x86;$(SolutionDir)Libs\lua\x86;$(SolutionDir)Libs\zlib\x86;$(SolutionDir)Libs\bass\x86;$(SolutionDir)Libs\ois\x86</LibraryPath> <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\x86;$(SolutionDir)Libs\spdlog\x86;$(SolutionDir)Libs\lua\x86;$(SolutionDir)Libs\zlib\x86;$(SolutionDir)Libs\vlc\x86;$(SolutionDir)Libs\bass\x86;$(SolutionDir)Libs\ois\x86</LibraryPath>
<TargetExt>.exe</TargetExt> <TargetExt>.exe</TargetExt>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ExecutablePath>$(ExecutablePath);$(DXSDK_DIR)Utilities\bin\x64</ExecutablePath> <ExecutablePath>$(ExecutablePath);$(DXSDK_DIR)Utilities\bin\x64</ExecutablePath>
<IncludePath>$(SolutionDir)Libs;$(SolutionDir)Libs\lua;$(SolutionDir)Libs\sol;$(SolutionDir)Libs\zlib;$(SolutionDir)Libs\spdlog;$(SolutionDir)Libs\ois;$(SolutionDir)Libs\bass;$(SolutionDir)Libs\srtparser;$(IncludePath)</IncludePath> <IncludePath>$(SolutionDir)Libs;$(SolutionDir)Libs\lua;$(SolutionDir)Libs\sol;$(SolutionDir)Libs\zlib;$(SolutionDir)Libs\spdlog;$(SolutionDir)Libs\ois;$(SolutionDir)Libs\vlc;$(SolutionDir)Libs\bass;$(SolutionDir)Libs\srtparser;$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\x64;$(SolutionDir)Libs\spdlog\x64;$(SolutionDir)Libs\lua\x64;$(SolutionDir)Libs\zlib\x64;$(SolutionDir)Libs\bass\x64;$(SolutionDir)Libs\ois\x64</LibraryPath> <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\x64;$(SolutionDir)Libs\spdlog\x64;$(SolutionDir)Libs\lua\x64;$(SolutionDir)Libs\zlib\x64;$(SolutionDir)Libs\vlc\x64;$(SolutionDir)Libs\bass\x64;$(SolutionDir)Libs\ois\x64</LibraryPath>
<TargetExt>.exe</TargetExt> <TargetExt>.exe</TargetExt>
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)Build\$(Configuration)\Bin\x64\</OutDir> <OutDir>$(SolutionDir)Build\$(Configuration)\Bin\x64\</OutDir>
@ -129,7 +129,7 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>comctl32.lib;lua53.lib;bass.lib;bassmix.lib;bass_fx.lib;D3DCompiler.lib;dxgi.lib;dxguid.lib;d3d11.lib;version.lib;zlib.lib;spdlogd.lib;OIS_d.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>comctl32.lib;lua53.lib;bass.lib;bassmix.lib;bass_fx.lib;D3DCompiler.lib;dxgi.lib;dxguid.lib;d3d11.lib;version.lib;zlib.lib;spdlogd.lib;libvlc.lib;libvlccore.lib;OIS_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<LargeAddressAware>true</LargeAddressAware> <LargeAddressAware>true</LargeAddressAware>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
@ -159,6 +159,7 @@ xcopy /D /Y /I /E "$(ProjectDir)Shaders\*.*" %ShaderDir%
xcopy /Y "$(SolutionDir)Libs\bass\x86\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\bass\x86\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\lua\x86\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\lua\x86\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\ois\x86\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\ois\x86\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\vlc\x86\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\zlib\x86\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\zlib\x86\*.dll" "$(TargetDir)"
xcopy /D /Y /I /E "$(SolutionDir)Scripts\Engine\*.*" %EngineDir% xcopy /D /Y /I /E "$(SolutionDir)Scripts\Engine\*.*" %EngineDir%
@ -194,7 +195,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>comctl32.lib;lua53.lib;bass.lib;bassmix.lib;bass_fx.lib;D3DCompiler.lib;dxgi.lib;dxguid.lib;d3d11.lib;version.lib;zlib.lib;spdlogd.lib;OIS_d.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>comctl32.lib;lua53.lib;bass.lib;bassmix.lib;bass_fx.lib;D3DCompiler.lib;dxgi.lib;dxguid.lib;d3d11.lib;version.lib;zlib.lib;spdlogd.lib;libvlc.lib;libvlccore.lib;OIS_d.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<LargeAddressAware>true</LargeAddressAware> <LargeAddressAware>true</LargeAddressAware>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
@ -224,6 +225,7 @@ xcopy /D /Y /I /E "$(ProjectDir)Shaders\*.*" %ShaderDir%
xcopy /Y "$(SolutionDir)Libs\bass\x64\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\bass\x64\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\lua\x64\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\lua\x64\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\ois\x64\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\ois\x64\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\vlc\x64\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
xcopy /D /Y /I /E "$(SolutionDir)Scripts\Engine\*.*" %EngineDir% xcopy /D /Y /I /E "$(SolutionDir)Scripts\Engine\*.*" %EngineDir%
@ -269,7 +271,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>comctl32.lib;lua53.lib;bass.lib;bassmix.lib;bass_fx.lib;D3DCompiler.lib;dxgi.lib;dxguid.lib;d3d11.lib;version.lib;zlib.lib;spdlog.lib;OIS.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>comctl32.lib;lua53.lib;bass.lib;bassmix.lib;bass_fx.lib;D3DCompiler.lib;dxgi.lib;dxguid.lib;d3d11.lib;version.lib;zlib.lib;spdlog.lib;libvlc.lib;libvlccore.lib;OIS.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<LargeAddressAware>true</LargeAddressAware> <LargeAddressAware>true</LargeAddressAware>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
@ -304,6 +306,7 @@ xcopy /D /Y /I /E "$(ProjectDir)Shaders\*.*" %ShaderDir%
xcopy /Y "$(SolutionDir)Libs\bass\x86\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\bass\x86\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\lua\x86\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\lua\x86\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\ois\x86\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\ois\x86\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\vlc\x86\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\zlib\x86\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\zlib\x86\*.dll" "$(TargetDir)"
xcopy /D /Y /I /E "$(SolutionDir)Scripts\Engine\*.*" %EngineDir% xcopy /D /Y /I /E "$(SolutionDir)Scripts\Engine\*.*" %EngineDir%
@ -351,7 +354,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation> <GenerateDebugInformation>false</GenerateDebugInformation>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<AdditionalDependencies>comctl32.lib;lua53.lib;bass.lib;bassmix.lib;bass_fx.lib;D3DCompiler.lib;dxgi.lib;dxguid.lib;d3d11.lib;version.lib;zlib.lib;spdlog.lib;OIS.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>comctl32.lib;lua53.lib;bass.lib;bassmix.lib;bass_fx.lib;D3DCompiler.lib;dxgi.lib;dxguid.lib;d3d11.lib;version.lib;zlib.lib;spdlog.lib;libvlc.lib;libvlccore.lib;OIS.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<LargeAddressAware>true</LargeAddressAware> <LargeAddressAware>true</LargeAddressAware>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
@ -385,6 +388,7 @@ xcopy /D /Y /I /E "$(ProjectDir)Shaders\*.*" %ShaderDir%
xcopy /Y "$(SolutionDir)Libs\bass\x64\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\bass\x64\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\lua\x64\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\lua\x64\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\ois\x64\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\ois\x64\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\vlc\x64\*.dll" "$(TargetDir)"
xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"
xcopy /D /Y /I /E "$(SolutionDir)Scripts\Engine\*.*" %EngineDir% xcopy /D /Y /I /E "$(SolutionDir)Scripts\Engine\*.*" %EngineDir%
@ -933,6 +937,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
<ClInclude Include="Specific\savegame\flatbuffers\ten_itemdata_generated.h" /> <ClInclude Include="Specific\savegame\flatbuffers\ten_itemdata_generated.h" />
<ClInclude Include="Specific\savegame\flatbuffers\ten_savegame_generated.h" /> <ClInclude Include="Specific\savegame\flatbuffers\ten_savegame_generated.h" />
<ClInclude Include="Specific\trutils.h" /> <ClInclude Include="Specific\trutils.h" />
<ClInclude Include="Specific\Video\Video.h" />
<ClInclude Include="Specific\winmain.h" /> <ClInclude Include="Specific\winmain.h" />
<ClInclude Include="framework.h" /> <ClInclude Include="framework.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
@ -1354,6 +1359,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
<ClCompile Include="Specific\Parallel.cpp" /> <ClCompile Include="Specific\Parallel.cpp" />
<ClCompile Include="Specific\RGBAColor8Byte.cpp" /> <ClCompile Include="Specific\RGBAColor8Byte.cpp" />
<ClCompile Include="Specific\trutils.cpp" /> <ClCompile Include="Specific\trutils.cpp" />
<ClCompile Include="Specific\Video\Video.cpp" />
<ClCompile Include="Specific\winmain.cpp" /> <ClCompile Include="Specific\winmain.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -23,6 +23,7 @@
#include <string> #include <string>
#include <queue> #include <queue>
#include <vector> #include <vector>
#include <vlc/vlc.h>
using namespace DirectX; using namespace DirectX;
using namespace DirectX::SimpleMath; using namespace DirectX::SimpleMath;