mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
309 lines
5.9 KiB
C
309 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 movie_state_t *cin_state;
|
|
static int cin_texture;
|
|
|
|
/*
|
|
==================
|
|
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;
|
|
}
|
|
|
|
static void SCR_CreateStartupVids( void )
|
|
{
|
|
file_t *f;
|
|
|
|
f = FS_Open( DEFAULT_VIDEOLIST_PATH, "w", false );
|
|
if( !f )
|
|
{
|
|
Con_Printf( S_ERROR "%s: can't open %s for write\n", __func__, DEFAULT_VIDEOLIST_PATH );
|
|
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 0
|
|
if( host_developer.value )
|
|
{
|
|
// don't run movies where we in developer-mode
|
|
cls.movienum = -1;
|
|
CL_CheckStartupDemos();
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
if( Sys_CheckParm( "-nointro" ) || 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, sizeof( 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;
|
|
cls.signon = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
==================
|
|
SCR_DrawCinematic
|
|
|
|
Returns true if a cinematic is active, meaning the view rendering
|
|
should be skipped
|
|
==================
|
|
*/
|
|
qboolean SCR_DrawCinematic( void )
|
|
{
|
|
if( !ref.initialized )
|
|
return false;
|
|
|
|
ref.dllFuncs.GL_SetRenderMode( kRenderNormal );
|
|
ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, R_GetBuiltinTexture( REF_BLACK_TEXTURE ));
|
|
|
|
if( !AVI_Think( cin_state ))
|
|
return SCR_NextMovie();
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
SCR_PlayCinematic
|
|
==================
|
|
*/
|
|
qboolean SCR_PlayCinematic( const char *arg )
|
|
{
|
|
int x, y, w, h;
|
|
const char *fullpath = FS_GetDiskPath( arg, false );
|
|
double video_ratio, screen_ratio, scale;
|
|
|
|
if( FS_FileExists( arg, false ) && !fullpath )
|
|
{
|
|
Con_Printf( S_ERROR "Couldn't load %s from packfile. Please extract it\n", arg );
|
|
return false;
|
|
}
|
|
|
|
AVI_OpenVideo( cin_state, fullpath, true, false );
|
|
if( !AVI_IsActive( cin_state ) || !AVI_GetVideoInfo( cin_state, &w, &h, NULL ))
|
|
{
|
|
AVI_CloseVideo( cin_state );
|
|
return false;
|
|
}
|
|
|
|
video_ratio = (double)w / (double)h;
|
|
screen_ratio = (double)refState.width / (double)refState.height;
|
|
|
|
if( video_ratio < screen_ratio )
|
|
scale = (double)refState.height / (double)h;
|
|
else
|
|
scale = (double)refState.width / (double)w;
|
|
|
|
w = Q_rint( w * scale );
|
|
h = Q_rint( h * scale );
|
|
|
|
if( video_ratio < screen_ratio )
|
|
{
|
|
x = (refState.width - w) / 2.0;
|
|
y = 0;
|
|
}
|
|
else
|
|
{
|
|
x = 0;
|
|
y = (refState.height - h) / 2.0;
|
|
}
|
|
|
|
if( AVI_HaveAudioTrack( cin_state ))
|
|
{
|
|
// begin streaming
|
|
S_StopAllSounds( true );
|
|
S_StartStreaming();
|
|
}
|
|
|
|
AVI_SetParm( cin_state,
|
|
AVI_RENDER_X, x,
|
|
AVI_RENDER_Y, y,
|
|
AVI_RENDER_W, w,
|
|
AVI_RENDER_H, h,
|
|
AVI_PARM_LAST );
|
|
|
|
UI_SetActiveMenu( false );
|
|
cls.state = ca_cinematic;
|
|
Con_FastClose();
|
|
cls.signon = 0;
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
SCR_StopCinematic
|
|
==================
|
|
*/
|
|
void SCR_StopCinematic( void )
|
|
{
|
|
if( cls.state != ca_cinematic )
|
|
return;
|
|
|
|
AVI_CloseVideo( cin_state );
|
|
S_StopStreaming();
|
|
|
|
cls.state = ca_disconnected;
|
|
cls.signon = 0;
|
|
|
|
UI_SetActiveMenu( true );
|
|
}
|
|
|
|
/*
|
|
==================
|
|
SCR_InitCinematic
|
|
==================
|
|
*/
|
|
void SCR_InitCinematic( void )
|
|
{
|
|
AVI_Initailize ();
|
|
cin_state = AVI_GetState( CIN_MAIN );
|
|
cin_texture = ref.dllFuncs.GL_CreateTexture( "*cintexture", 64, 64, NULL, TF_NOMIPMAP|TF_CLAMP );
|
|
}
|
|
|
|
int SCR_GetCinematicTexture( void )
|
|
{
|
|
return cin_texture;
|
|
}
|
|
|
|
/*
|
|
==================
|
|
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();
|
|
}
|