This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/engine/client/cl_video.c

306 lines
6.1 KiB
C
Raw Normal View History

2011-05-09 22:00:00 +02:00
/*
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.
*/
2009-11-23 22:00:00 +01:00
#include "common.h"
#include "client.h"
2010-12-27 22:00:00 +01:00
#include "gl_local.h"
2009-11-23 22:00:00 +01:00
/*
=================================================================
2010-09-30 22:00:00 +02:00
AVI PLAYING
2009-11-23 22:00:00 +01:00
=================================================================
*/
2010-09-30 22:00:00 +02:00
static long 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;
2009-11-23 22:00:00 +01:00
/*
==================
2010-09-30 22:00:00 +02:00
SCR_NextMovie
Called when a demo or cinematic finishes
If the "nextmovie" cvar is set, that command will be issued
2009-11-23 22:00:00 +01:00
==================
*/
2010-10-26 22:00:00 +02:00
qboolean SCR_NextMovie( void )
2009-11-23 22:00:00 +01:00
{
2010-09-30 22:00:00 +02:00
string str;
2009-11-23 22:00:00 +01:00
2010-09-30 22:00:00 +02:00
if( cls.movienum == -1 )
2016-11-14 22:00:00 +01:00
{
2017-06-23 23:00:00 +02:00
S_StopAllSounds( true );
2016-11-14 22:00:00 +01:00
SCR_StopCinematic();
2010-09-30 22:00:00 +02:00
return false; // don't play movies
2016-11-14 22:00:00 +01:00
}
2009-11-23 22:00:00 +01:00
2010-09-30 22:00:00 +02:00
if( !cls.movies[cls.movienum][0] || cls.movienum == MAX_MOVIES )
2009-11-23 22:00:00 +01:00
{
2017-06-23 23:00:00 +02:00
S_StopAllSounds( true );
2016-11-14 22:00:00 +01:00
SCR_StopCinematic();
2010-09-30 22:00:00 +02:00
cls.movienum = -1;
return false;
2009-11-23 22:00:00 +01:00
}
2011-03-09 22:00:00 +01:00
Q_snprintf( str, MAX_STRING, "movie %s full\n", cls.movies[cls.movienum] );
2009-11-23 22:00:00 +01:00
2010-09-30 22:00:00 +02:00
Cbuf_InsertText( str );
cls.movienum++;
2009-11-23 22:00:00 +01:00
2010-09-30 22:00:00 +02:00
return true;
2009-11-23 22:00:00 +01:00
}
2010-10-09 22:00:00 +02:00
void SCR_CreateStartupVids( void )
2009-11-23 22:00:00 +01:00
{
2010-10-09 22:00:00 +02:00
file_t *f;
2018-03-13 22:00:00 +01:00
f = FS_Open( DEFAULT_VIDEOLIST_PATH, "w", false );
2010-10-09 22:00:00 +02:00
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 );
}
2010-09-30 22:00:00 +02:00
2010-10-09 22:00:00 +02:00
void SCR_CheckStartupVids( void )
{
int c = 0;
2011-03-01 22:00:00 +01:00
char *afile, *pfile;
2010-10-09 22:00:00 +02:00
string token;
2018-03-13 22:00:00 +01:00
if( Sys_CheckParm( "-nointro" ) || host_developer.value || cls.demonum != -1 || GameState->nextstate != STATE_RUNFRAME )
2010-09-30 22:00:00 +02:00
{
// don't run movies where we in developer-mode
cls.movienum = -1;
return;
}
2018-03-13 22:00:00 +01:00
if( !FS_FileExists( DEFAULT_VIDEOLIST_PATH, false ))
2010-10-09 22:00:00 +02:00
SCR_CreateStartupVids();
2018-03-13 22:00:00 +01:00
afile = FS_LoadFile( DEFAULT_VIDEOLIST_PATH, NULL, false );
2011-03-01 22:00:00 +01:00
if( !afile ) return; // something bad happens
pfile = afile;
2010-10-09 22:00:00 +02:00
2011-03-01 22:00:00 +01:00
while(( pfile = COM_ParseFile( pfile, token )) != NULL )
2010-10-09 22:00:00 +02:00
{
2011-03-09 22:00:00 +01:00
Q_strncpy( cls.movies[c], token, sizeof( cls.movies[0] ));
2010-10-09 22:00:00 +02:00
if( ++c > MAX_MOVIES - 1 )
{
2018-03-13 22:00:00 +01:00
Con_Printf( S_WARN "too many movies (%d) specified in %s\n", MAX_MOVIES, DEFAULT_VIDEOLIST_PATH );
2010-10-09 22:00:00 +02:00
break;
}
2010-09-30 22:00:00 +02:00
}
2009-11-23 22:00:00 +01:00
2011-03-01 22:00:00 +01:00
Mem_Free( afile );
2010-09-30 22:00:00 +02:00
2010-10-09 22:00:00 +02:00
// run cinematic
2018-03-13 22:00:00 +01:00
cls.movienum = 0;
SCR_NextMovie ();
Cbuf_Execute();
2010-09-30 22:00:00 +02:00
}
2009-11-23 22:00:00 +01:00
/*
==================
SCR_RunCinematic
==================
*/
void SCR_RunCinematic( void )
{
2010-12-27 22:00:00 +01:00
if( cls.state != ca_cinematic )
return;
2010-09-30 22:00:00 +02:00
if( !AVI_IsActive( cin_state ))
2016-12-09 22:00:00 +01:00
{
SCR_NextMovie( );
2009-11-23 22:00:00 +01:00
return;
2016-12-09 22:00:00 +01:00
}
2009-11-23 22:00:00 +01:00
2010-12-27 22:00:00 +01:00
if( UI_IsVisible( ))
2009-11-23 22:00:00 +01:00
{
2010-12-27 22:00:00 +01:00
// 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;
2017-02-13 22:00:00 +01:00
cls.signon = 0;
2010-12-27 22:00:00 +01:00
return;
2009-11-23 22:00:00 +01:00
}
2010-10-09 22:00:00 +02:00
// advances cinematic time (ignores maxfps and host_framerate settings)
cin_time += host.realframetime;
2009-11-23 22:00:00 +01:00
2010-09-30 22:00:00 +02:00
// stop the video after it finishes
if( cin_time > video_duration + 0.1f )
2009-11-23 22:00:00 +01:00
{
2010-09-30 22:00:00 +02:00
SCR_NextMovie( );
2009-11-23 22:00:00 +01:00
return;
}
2010-09-30 22:00:00 +02:00
// read the next frame
cin_frame = AVI_GetVideoFrameNumber( cin_state, cin_time );
2009-11-23 22:00:00 +01:00
}
/*
==================
SCR_DrawCinematic
Returns true if a cinematic is active, meaning the view rendering
should be skipped
==================
*/
2010-10-26 22:00:00 +02:00
qboolean SCR_DrawCinematic( void )
2009-11-23 22:00:00 +01:00
{
2010-09-30 22:00:00 +02:00
static int last_frame = -1;
2010-10-26 22:00:00 +02:00
qboolean redraw = false;
2010-10-01 22:00:00 +02:00
byte *frame = NULL;
2010-09-30 22:00:00 +02:00
2010-12-27 22:00:00 +01:00
if( !glw_state.initialized || cin_time <= 0.0f )
2009-11-23 22:00:00 +01:00
return false;
2010-06-17 22:00:00 +02:00
2010-09-30 22:00:00 +02:00
if( cin_frame != last_frame )
{
2010-10-01 22:00:00 +02:00
frame = AVI_GetVideoFrame( cin_state, cin_frame );
2010-09-30 22:00:00 +02:00
last_frame = cin_frame;
redraw = true;
}
2009-11-23 22:00:00 +01:00
2017-02-15 22:00:00 +01:00
R_DrawStretchRaw( 0, 0, glState.width, glState.height, xres, yres, frame, redraw );
2009-11-23 22:00:00 +01:00
return true;
}
2010-09-30 22:00:00 +02:00
2009-11-23 22:00:00 +01:00
/*
==================
SCR_PlayCinematic
==================
*/
2010-10-26 22:00:00 +02:00
qboolean SCR_PlayCinematic( const char *arg )
2009-11-23 22:00:00 +01:00
{
2010-09-30 22:00:00 +02:00
string path;
const char *fullpath;
2011-03-08 22:00:00 +01:00
fullpath = FS_GetDiskPath( arg, false );
2009-11-23 22:00:00 +01:00
2011-03-08 22:00:00 +01:00
if( FS_FileExists( arg, false ) && !fullpath )
2009-11-23 22:00:00 +01:00
{
2011-04-09 22:00:00 +02:00
MsgDev( D_ERROR, "Couldn't load %s from packfile. Please extract it\n", path );
2010-09-30 22:00:00 +02:00
return false;
2009-11-23 22:00:00 +01:00
}
2017-03-08 22:00:00 +01:00
AVI_OpenVideo( cin_state, fullpath, true, false );
2010-09-30 22:00:00 +02:00
if( !AVI_IsActive( cin_state ))
{
AVI_CloseVideo( cin_state );
return false;
}
2009-11-23 22:00:00 +01:00
2010-09-30 22:00:00 +02:00
if( !( AVI_GetVideoInfo( cin_state, &xres, &yres, &video_duration ))) // couldn't open this at all.
2009-11-23 22:00:00 +01:00
{
2010-09-30 22:00:00 +02:00
AVI_CloseVideo( cin_state );
2009-11-23 22:00:00 +01:00
return false;
}
2010-09-30 22:00:00 +02:00
if( AVI_GetAudioInfo( cin_state, &cin_audio ))
2009-11-23 22:00:00 +01:00
{
2010-09-30 22:00:00 +02:00
// begin streaming
2017-06-23 23:00:00 +02:00
S_StopAllSounds( true );
2010-09-30 22:00:00 +02:00
S_StartStreaming();
2009-11-23 22:00:00 +01:00
}
2010-07-18 22:00:00 +02:00
UI_SetActiveMenu( false );
2009-11-23 22:00:00 +01:00
cls.state = ca_cinematic;
2010-09-30 22:00:00 +02:00
cin_time = 0.0f;
2017-02-13 22:00:00 +01:00
cls.signon = 0;
2010-09-30 22:00:00 +02:00
return true;
}
2009-11-23 22:00:00 +01:00
2010-09-30 22:00:00 +02:00
long SCR_GetAudioChunk( char *rawdata, long length )
{
int r;
2009-11-23 22:00:00 +01:00
2010-09-30 22:00:00 +02:00
r = AVI_GetAudioChunk( cin_state, rawdata, cin_audio.loopStart, length );
2011-04-09 22:00:00 +02:00
cin_audio.loopStart += r; // advance play position
2010-09-30 22:00:00 +02:00
return r;
}
wavdata_t *SCR_GetMovieInfo( void )
{
if( AVI_IsActive( cin_state ))
return &cin_audio;
return NULL;
}
/*
==================
SCR_StopCinematic
==================
*/
void SCR_StopCinematic( void )
{
2010-10-02 22:00:00 +02:00
if( cls.state != ca_cinematic )
return;
2010-09-30 22:00:00 +02:00
AVI_CloseVideo( cin_state );
S_StopStreaming();
cin_time = 0.0f;
cls.state = ca_disconnected;
2017-02-13 22:00:00 +01:00
cls.signon = 0;
2010-09-30 22:00:00 +02:00
UI_SetActiveMenu( true );
}
/*
==================
SCR_InitCinematic
==================
*/
void SCR_InitCinematic( void )
{
2011-03-09 22:00:00 +01:00
AVI_Initailize ();
2010-09-30 22:00:00 +02:00
cin_state = AVI_GetState( CIN_MAIN );
}
/*
==================
SCR_FreeCinematic
==================
*/
void SCR_FreeCinematic( void )
{
2010-12-21 22:00:00 +01:00
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 );
2011-03-09 22:00:00 +01:00
AVI_Shutdown();
2009-11-23 22:00:00 +01:00
}