mirror of
https://github.com/FWGS/xash3d-fwgs
synced 2024-11-25 11:19:59 +01:00
5e0a0765ce
The `.editorconfig` file in this repo is configured to trim all trailing whitespace regardless of whether the line is modified. Trims all trailing whitespace in the repository to make the codebase easier to work with in editors that respect `.editorconfig`. `git blame` becomes less useful on these lines but it already isn't very useful. Commands: ``` find . -type f -name '*.h' -exec sed --in-place 's/[[:space:]]\+$//' {} \+ find . -type f -name '*.c' -exec sed --in-place 's/[[:space:]]\+$//' {} \+ ```
311 lines
5.9 KiB
C
311 lines
5.9 KiB
C
/*
|
|
cl_video.c - avi video player
|
|
Copyright (C) 2009 Uncle Mike
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 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 General Public License for more details.
|
|
*/
|
|
|
|
#include "common.h"
|
|
#include "client.h"
|
|
|
|
/*
|
|
=================================================================
|
|
|
|
AVI PLAYING
|
|
|
|
=================================================================
|
|
*/
|
|
|
|
static int xres, yres;
|
|
static float video_duration;
|
|
static float cin_time;
|
|
static int cin_frame;
|
|
static wavdata_t cin_audio;
|
|
static movie_state_t *cin_state;
|
|
|
|
/*
|
|
==================
|
|
SCR_NextMovie
|
|
|
|
Called when a demo or cinematic finishes
|
|
If the "nextmovie" cvar is set, that command will be issued
|
|
==================
|
|
*/
|
|
qboolean SCR_NextMovie( void )
|
|
{
|
|
string str;
|
|
|
|
if( cls.movienum == -1 )
|
|
{
|
|
S_StopAllSounds( true );
|
|
SCR_StopCinematic();
|
|
CL_CheckStartupDemos();
|
|
return false; // don't play movies
|
|
}
|
|
|
|
if( !cls.movies[cls.movienum][0] || cls.movienum == MAX_MOVIES )
|
|
{
|
|
S_StopAllSounds( true );
|
|
SCR_StopCinematic();
|
|
cls.movienum = -1;
|
|
CL_CheckStartupDemos();
|
|
return false;
|
|
}
|
|
|
|
Q_snprintf( str, MAX_STRING, "movie %s full\n", cls.movies[cls.movienum] );
|
|
|
|
Cbuf_InsertText( str );
|
|
cls.movienum++;
|
|
|
|
return true;
|
|
}
|
|
|
|
void SCR_CreateStartupVids( void )
|
|
{
|
|
file_t *f;
|
|
|
|
f = FS_Open( DEFAULT_VIDEOLIST_PATH, "w", false );
|
|
if( !f ) return;
|
|
|
|
// make standard video playlist: sierra, valve
|
|
FS_Print( f, "media/sierra.avi\n" );
|
|
FS_Print( f, "media/valve.avi\n" );
|
|
FS_Close( f );
|
|
}
|
|
|
|
void SCR_CheckStartupVids( void )
|
|
{
|
|
int c = 0;
|
|
byte *afile;
|
|
char *pfile;
|
|
string token;
|
|
|
|
if( Sys_CheckParm( "-nointro" ) || host_developer.value || cls.demonum != -1 || GameState->nextstate != STATE_RUNFRAME )
|
|
{
|
|
// don't run movies where we in developer-mode
|
|
cls.movienum = -1;
|
|
CL_CheckStartupDemos();
|
|
return;
|
|
}
|
|
|
|
if( !FS_FileExists( DEFAULT_VIDEOLIST_PATH, false ))
|
|
SCR_CreateStartupVids();
|
|
|
|
afile = FS_LoadFile( DEFAULT_VIDEOLIST_PATH, NULL, false );
|
|
if( !afile ) return; // something bad happens
|
|
|
|
pfile = (char *)afile;
|
|
|
|
while(( pfile = COM_ParseFile( pfile, token )) != NULL )
|
|
{
|
|
Q_strncpy( cls.movies[c], token, sizeof( cls.movies[0] ));
|
|
|
|
if( ++c > MAX_MOVIES - 1 )
|
|
{
|
|
Con_Printf( S_WARN "too many movies (%d) specified in %s\n", MAX_MOVIES, DEFAULT_VIDEOLIST_PATH );
|
|
break;
|
|
}
|
|
}
|
|
|
|
Mem_Free( afile );
|
|
|
|
// run cinematic
|
|
cls.movienum = 0;
|
|
SCR_NextMovie ();
|
|
Cbuf_Execute();
|
|
}
|
|
|
|
/*
|
|
==================
|
|
SCR_RunCinematic
|
|
==================
|
|
*/
|
|
void SCR_RunCinematic( void )
|
|
{
|
|
if( cls.state != ca_cinematic )
|
|
return;
|
|
|
|
if( !AVI_IsActive( cin_state ))
|
|
{
|
|
SCR_NextMovie( );
|
|
return;
|
|
}
|
|
|
|
if( UI_IsVisible( ))
|
|
{
|
|
// these can happens when user set +menu_ option to cmdline
|
|
AVI_CloseVideo( cin_state );
|
|
cls.state = ca_disconnected;
|
|
Key_SetKeyDest( key_menu );
|
|
S_StopStreaming();
|
|
cls.movienum = -1;
|
|
cin_time = 0.0f;
|
|
cls.signon = 0;
|
|
return;
|
|
}
|
|
|
|
// advances cinematic time (ignores maxfps and host_framerate settings)
|
|
cin_time += host.realframetime;
|
|
|
|
// stop the video after it finishes
|
|
if( cin_time > video_duration + 0.1f )
|
|
{
|
|
SCR_NextMovie( );
|
|
return;
|
|
}
|
|
|
|
// read the next frame
|
|
cin_frame = AVI_GetVideoFrameNumber( cin_state, cin_time );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
SCR_DrawCinematic
|
|
|
|
Returns true if a cinematic is active, meaning the view rendering
|
|
should be skipped
|
|
==================
|
|
*/
|
|
qboolean SCR_DrawCinematic( void )
|
|
{
|
|
static int last_frame = -1;
|
|
qboolean redraw = false;
|
|
byte *frame = NULL;
|
|
|
|
if( !ref.initialized || cin_time <= 0.0f )
|
|
return false;
|
|
|
|
if( cin_frame != last_frame )
|
|
{
|
|
frame = AVI_GetVideoFrame( cin_state, cin_frame );
|
|
last_frame = cin_frame;
|
|
redraw = true;
|
|
}
|
|
|
|
ref.dllFuncs.R_DrawStretchRaw( 0, 0, refState.width, refState.height, xres, yres, frame, redraw );
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
SCR_PlayCinematic
|
|
==================
|
|
*/
|
|
qboolean SCR_PlayCinematic( const char *arg )
|
|
{
|
|
string path;
|
|
const char *fullpath;
|
|
|
|
fullpath = FS_GetDiskPath( arg, false );
|
|
|
|
if( FS_FileExists( arg, false ) && !fullpath )
|
|
{
|
|
Con_Printf( S_ERROR "Couldn't load %s from packfile. Please extract it\n", path );
|
|
return false;
|
|
}
|
|
|
|
AVI_OpenVideo( cin_state, fullpath, true, false );
|
|
if( !AVI_IsActive( cin_state ))
|
|
{
|
|
AVI_CloseVideo( cin_state );
|
|
return false;
|
|
}
|
|
|
|
if( !( AVI_GetVideoInfo( cin_state, &xres, &yres, &video_duration ))) // couldn't open this at all.
|
|
{
|
|
AVI_CloseVideo( cin_state );
|
|
return false;
|
|
}
|
|
|
|
if( AVI_GetAudioInfo( cin_state, &cin_audio ))
|
|
{
|
|
// begin streaming
|
|
S_StopAllSounds( true );
|
|
S_StartStreaming();
|
|
}
|
|
|
|
UI_SetActiveMenu( false );
|
|
cls.state = ca_cinematic;
|
|
Con_FastClose();
|
|
cin_time = 0.0f;
|
|
cls.signon = 0;
|
|
|
|
return true;
|
|
}
|
|
|
|
int SCR_GetAudioChunk( char *rawdata, int length )
|
|
{
|
|
int r;
|
|
|
|
r = AVI_GetAudioChunk( cin_state, rawdata, cin_audio.loopStart, length );
|
|
cin_audio.loopStart += r; // advance play position
|
|
|
|
return r;
|
|
}
|
|
|
|
wavdata_t *SCR_GetMovieInfo( void )
|
|
{
|
|
if( AVI_IsActive( cin_state ))
|
|
return &cin_audio;
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
SCR_StopCinematic
|
|
==================
|
|
*/
|
|
void SCR_StopCinematic( void )
|
|
{
|
|
if( cls.state != ca_cinematic )
|
|
return;
|
|
|
|
AVI_CloseVideo( cin_state );
|
|
S_StopStreaming();
|
|
cin_time = 0.0f;
|
|
|
|
cls.state = ca_disconnected;
|
|
cls.signon = 0;
|
|
|
|
UI_SetActiveMenu( true );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
SCR_InitCinematic
|
|
==================
|
|
*/
|
|
void SCR_InitCinematic( void )
|
|
{
|
|
AVI_Initailize ();
|
|
cin_state = AVI_GetState( CIN_MAIN );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
SCR_FreeCinematic
|
|
==================
|
|
*/
|
|
void SCR_FreeCinematic( void )
|
|
{
|
|
movie_state_t *cin_state;
|
|
|
|
// release videos
|
|
cin_state = AVI_GetState( CIN_LOGO );
|
|
AVI_CloseVideo( cin_state );
|
|
|
|
cin_state = AVI_GetState( CIN_MAIN );
|
|
AVI_CloseVideo( cin_state );
|
|
|
|
AVI_Shutdown();
|
|
}
|