+void CL_CloseVideo( clvideo_t * video )
+{
+ if( !video || video->state == CLVIDEO_UNUSED )
+ return;
+
+ 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 )
+{
+ int destframe;
+
+ if( video->state == CLVIDEO_FIRSTFRAME )
+ destframe = 0;
+ else
+ destframe = (int)((realtime - video->starttime) * video->framerate);
+ if( destframe < 0 )
+ destframe = 0;
+ if( video->framenum < destframe ) {
+ do {
+ video->framenum++;
+ if( dpvsimpledecode_video( video->stream, video->imagedata, cl_videormask,
+ cl_videogmask, cl_videobmask, cl_videobytesperpixel,
+ cl_videobytesperpixel * video->cpif.width )
+ ) { // finished?
+ CL_RestartVideo( video );
+ if( video->state == CLVIDEO_PLAY )
+ video->state = CLVIDEO_FIRSTFRAME;
+ return;
+ }
+ } while( video->framenum < destframe );
+ R_UpdateTexture( video->cpif.tex, (unsigned char *)video->imagedata, 0, 0, video->cpif.width, video->cpif.height );
+ }
+}
+
+void CL_VideoFrame( void ) // update all videos
+{
+ int i;
+ clvideo_t *video;
+
+ if (!cl_num_videos)
+ return;
+
+ for( video = cl_videos, i = 0 ; i < cl_num_videos ; video++, i++ )
+ if( video->state != CLVIDEO_UNUSED && !video->suspended )
+ {
+ if( realtime - video->lasttime > CLTHRESHOLD )
+ SuspendVideo( video );
+ else if( video->state == CLVIDEO_PAUSE )
+ video->starttime = realtime - video->framenum * video->framerate;
+ else
+ VideoFrame( video );
+ }
+
+ if( cl_videos->state == CLVIDEO_FIRSTFRAME )
+ CL_VideoStop();
+
+ // reduce range to exclude unnecessary entries
+ while (cl_num_videos > 0 && cl_videos[cl_num_videos-1].state == CLVIDEO_UNUSED)
+ cl_num_videos--;
+}
+
+void CL_Video_Shutdown( void )
+{
+ int i;
+ for( i = 0 ; i < cl_num_videos ; i++ )
+ CL_CloseVideo( &cl_videos[ i ] );
+}
+
+void CL_PurgeOwner( int owner )
+{
+ int i;
+ for( i = 0 ; i < cl_num_videos ; i++ )
+ if( cl_videos[ i ].ownertag == owner )
+ CL_CloseVideo( &cl_videos[ i ] );
+}
+
+int cl_videoplaying = false; // old, but still supported
+