From 59d5ffaf49cffaec27871bfe53c9472d1f3d4259 Mon Sep 17 00:00:00 2001 From: black Date: Sat, 4 Dec 2004 21:08:13 +0000 Subject: [PATCH] -Added video streaming support to the new VM -Changed again a lot of CL_Video (mostly bugs and logical errors) -It doesnt append the prefix now, but only checks whether it matches or not - if it doesnt it doesnt load the video. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4828 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_video.c | 64 +++++++++----------------- cl_video.h | 14 +++--- gl_draw.c | 12 ++--- prvm_cmds.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 160 insertions(+), 58 deletions(-) diff --git a/cl_video.c b/cl_video.c index d3804da6..7707dd77 100644 --- a/cl_video.c +++ b/cl_video.c @@ -53,7 +53,7 @@ static qboolean WakeVideo( clvideo_t * video ) if( !video->suspended ) return true; video->suspended = false; - + if( video->state == CLVIDEO_FIRSTFRAME ) if( !OpenStream( video ) ) { video->state = CLVIDEO_UNUSED; @@ -66,6 +66,7 @@ static qboolean WakeVideo( clvideo_t * video ) // update starttime video->starttime += realtime - video->lasttime; + return true; } @@ -73,8 +74,9 @@ static clvideo_t* OpenVideo( clvideo_t *video, char *filename, char *name, int o { strncpy( video->filename, filename, MAX_QPATH ); video->ownertag = owner; - strncpy( video->cpif.name, CLVIDEOPREFIX, MAX_QPATH ); - strncat( video->cpif.name, name, MAX_QPATH - sizeof( CLVIDEOPREFIX ) ); + if( strncmp( name, CLVIDEOPREFIX, sizeof( CLVIDEOPREFIX ) - 1 ) ) + return NULL; + strncpy( video->cpif.name, name, MAX_QPATH ); if( !OpenStream( video ) ) return NULL; @@ -122,38 +124,23 @@ clvideo_t* CL_GetVideo( char *name ) if( video->suspended ) if( !WakeVideo( video ) ) return NULL; + else if( video->state == CLVIDEO_RESETONWAKEUP ) + video->framenum = -1; + video->lasttime = realtime; return video; } -void CL_StartVideo( clvideo_t * video ) -{ - if( !video ) - return; - - video->starttime = video->lasttime = realtime; - video->framenum = -1; - video->state = CLVIDEO_PLAY; -} - -void CL_LoopVideo( clvideo_t * video ) -{ - if( !video ) - return; - - video->starttime = video->lasttime = realtime; - video->framenum = -1; - video->state = CLVIDEO_LOOP; -} - -void CL_PauseVideo( clvideo_t * video ) +void CL_SetVideoState( clvideo_t *video, clvideostate_t state ) { if( !video ) return; - video->state = CLVIDEO_PAUSE; video->lasttime = realtime; + video->state = state; + if( state == CLVIDEO_FIRSTFRAME ) + CL_RestartVideo( video ); } void CL_RestartVideo( clvideo_t *video ) @@ -163,16 +150,10 @@ void CL_RestartVideo( clvideo_t *video ) video->starttime = video->lasttime = realtime; video->framenum = -1; -} - -void CL_StopVideo( clvideo_t * video ) -{ - if( !video ) - return; - video->lasttime = realtime; - video->framenum = -1; - video->state = CLVIDEO_FIRSTFRAME; + dpvsimpledecode_close( video->stream ); + if( !OpenStream( video ) ) + video->state = CLVIDEO_UNUSED; } void CL_CloseVideo( clvideo_t * video ) @@ -180,14 +161,14 @@ void CL_CloseVideo( clvideo_t * video ) if( !video || video->state == CLVIDEO_UNUSED ) return; - video->state = CLVIDEO_UNUSED; - if( !video->suspended || video->state != CLVIDEO_FIRSTFRAME ) dpvsimpledecode_close( video->stream ); if( !video->suspended ) { Mem_Free( video->imagedata ); R_FreeTexture( video->cpif.tex ); } + + video->state = CLVIDEO_UNUSED; } static void VideoFrame( clvideo_t *video ) @@ -207,10 +188,8 @@ static void VideoFrame( clvideo_t *video ) cl_videogmask, cl_videobmask, cl_videobytesperpixel, cl_videobytesperpixel * video->cpif.width ) ) { // finished? - video->framenum = -1; - if( video->state == CLVIDEO_LOOP ) - video->starttime = realtime; - else if( video->state == CLVIDEO_PLAY ) + CL_RestartVideo( video ); + if( video->state == CLVIDEO_PLAY ) video->state = CLVIDEO_FIRSTFRAME; return; } @@ -267,12 +246,13 @@ void CL_VideoStart(char *filename) { if( videoarray->state != CLVIDEO_UNUSED ) CL_CloseVideo( videoarray ); - if( !OpenVideo( videoarray, filename, filename, 0 ) ) + if( !OpenVideo( videoarray, filename, va( CLVIDEOPREFIX "%s", filename ), 0 ) ) return; cl_videoplaying = true; - CL_StartVideo( videoarray ); + CL_SetVideoState( videoarray, CLVIDEO_PLAY ); + CL_RestartVideo( videoarray ); } void CL_VideoStop(void) diff --git a/cl_video.h b/cl_video.h index 9a6ad8c1..5d9cd2f1 100644 --- a/cl_video.h +++ b/cl_video.h @@ -3,16 +3,20 @@ #define CL_VIDEO_H #define MAXCLVIDEOS 64 + 1 // 1 video is reserved for the cinematic mode -#define CLVIDEOPREFIX "_" +#define CLVIDEOPREFIX "_video/" #define CLTHRESHOLD 2.0 -typedef enum clvideostate_s +#define MENUOWNER 1 + +typedef enum clvideostate_e { CLVIDEO_UNUSED, CLVIDEO_PLAY, CLVIDEO_LOOP, CLVIDEO_PAUSE, CLVIDEO_FIRSTFRAME, + CLVIDEO_RESETONWAKEUP, + CLVIDEO_STATECOUNT } clvideostate_t; typedef struct clvideo_s @@ -40,11 +44,9 @@ typedef struct clvideo_s clvideo_t* CL_OpenVideo( char *filename, char *name, int owner ); clvideo_t* CL_GetVideo( char *name ); -void CL_StartVideo( clvideo_t * video ); -void CL_LoopVideo( clvideo_t * video ); -void CL_PauseVideo( clvideo_t * video ); -void CL_StopVideo( clvideo_t * video ); +void CL_SetVideoState( clvideo_t *video, clvideostate_t state ); void CL_RestartVideo( clvideo_t *video ); + void CL_CloseVideo( clvideo_t * video ); void CL_PurgeOwner( int owner ); diff --git a/gl_draw.c b/gl_draw.c index 9c801c43..378bf682 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -268,12 +268,6 @@ cachepic_t *Draw_CachePic (char *path) cachepic_t *pic; qpic_t *p; - crc = CRC_Block(path, strlen(path)); - hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE; - for (pic = cachepichash[hashkey];pic;pic = pic->chain) - if (!strcmp (path, pic->name)) - return pic; - if (!strncmp(CLVIDEOPREFIX, path, sizeof(CLVIDEOPREFIX) - 1)) { clvideo_t *video; @@ -282,6 +276,12 @@ cachepic_t *Draw_CachePic (char *path) return &video->cpif; } + crc = CRC_Block(path, strlen(path)); + hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE; + for (pic = cachepichash[hashkey];pic;pic = pic->chain) + if (!strcmp (path, pic->name)) + return pic; + if (numcachepics == MAX_CACHED_PICS) Sys_Error ("numcachepics == MAX_CACHED_PICS"); pic = cachepics + (numcachepics++); diff --git a/prvm_cmds.c b/prvm_cmds.c index 56c9f4bc..805ab1bd 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -112,8 +112,8 @@ perhaps only : Menu : WriteMsg WriteString(string data, float dest, float desto) WriteEntity(entity data, float dest, float desto) -Client & Menu : draw functions -=============================== +Client & Menu : draw functions & video functions +=================================================== float iscachedpic(string pic) string precache_pic(string pic) @@ -125,7 +125,12 @@ float drawfill(vector position, vector size, vector rgb, float alpha, float flag drawsetcliparea(float x, float y, float width, float height) drawresetcliparea() vector getimagesize(string pic) - + +float cin_open(string file, string name) +void cin_close(string name) +void cin_setstate(string name, float type) +float cin_getstate(string name) +void cin_restart(string name) ============================================================================== menu cmd list: @@ -154,6 +159,8 @@ string gethostcachestring(float type, float hostnr) #include "clprogdefs.h" #include "mprogdefs.h" +#include "cl_video.h" + //============================================================================ // nice helper macros @@ -2818,6 +2825,113 @@ void VM_getimagesize(void) PRVM_G_VECTOR(OFS_RETURN)[2] = 0; } +// CL_Video interface functions + +/* +======================== +VM_cin_open + +float cin_open(string file, string name) +======================== +*/ +void VM_cin_open( void ) +{ + char *file; + char *name; + + file = PRVM_G_STRING( OFS_PARM0 ); + name = PRVM_G_STRING( OFS_PARM1 ); + + VM_CheckEmptyString( file ); + VM_CheckEmptyString( name ); + + if( CL_OpenVideo( file, name, MENUOWNER ) ) + PRVM_G_FLOAT( OFS_RETURN ) = 1; + else + PRVM_G_FLOAT( OFS_RETURN ) = 0; +} + +/* +======================== +VM_cin_close + +void cin_close(string name) +======================== +*/ +void VM_cin_close( void ) +{ + char *name; + + name = PRVM_G_STRING( OFS_PARM0 ); + VM_CheckEmptyString( name ); + + CL_CloseVideo( CL_GetVideo( name ) ); +} + +/* +======================== +VM_cin_setstate +void cin_setstate(string name, float type) +======================== +*/ +void VM_cin_setstate( void ) +{ + char *name; + clvideostate_t state; + clvideo_t *video; + + name = PRVM_G_STRING( OFS_PARM0 ); + VM_CheckEmptyString( name ); + + state = PRVM_G_FLOAT( OFS_PARM1 ); + + video = CL_GetVideo( name ); + if( video && state > CLVIDEO_UNUSED && state < CLVIDEO_STATECOUNT ) + CL_SetVideoState( video, state ); +} + +/* +======================== +VM_cin_getstate + +float cin_getstate(string name) +======================== +*/ +void VM_cin_getstate( void ) +{ + char *name; + clvideo_t *video; + + name = PRVM_G_STRING( OFS_PARM0 ); + VM_CheckEmptyString( name ); + + video = CL_GetVideo( name ); + if( video ) + PRVM_G_FLOAT( OFS_RETURN ) = (int)video->state; + else + PRVM_G_FLOAT( OFS_RETURN ) = 0; +} + +/* +======================== +VM_cin_restart + +void cin_restart(string name) +======================== +*/ +void VM_cin_restart( void ) +{ + char *name; + clvideo_t *video; + + name = PRVM_G_STRING( OFS_PARM0 ); + VM_CheckEmptyString( name ); + + video = CL_GetVideo( name ); + if( video ) + CL_RestartVideo( video ); +} + void VM_Cmd_Init(void) { // only init the stuff for the current prog @@ -2838,6 +2952,7 @@ void VM_Cmd_Reset(void) } Mem_FreePool(&VM_STRINGS_MEMPOOL); + CL_PurgeOwner( MENUOWNER ); VM_Search_Reset(); VM_Files_CloseAll(); } @@ -3383,7 +3498,12 @@ prvm_builtin_t vm_m_builtins[] = { VM_drawsetcliparea, VM_drawresetcliparea, VM_getimagesize,// 460 - e10, // 470 + VM_cin_open, + VM_cin_close, + VM_cin_setstate, + VM_cin_getstate, + VM_cin_restart, // 465 + 0,0,0,0,0, // 470 e10, // 480 e10, // 490 e10, // 500 -- 2.39.2