310 lines
5.9 KiB
310 lines
5.9 KiB
/* |
|
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(); |
|
}
|
|
|