4 #include "dpvsimpledecode.h"
6 // constants (and semi-constants)
7 static int cl_videormask;
8 static int cl_videobmask;
9 static int cl_videogmask;
10 static int cl_videobytesperpixel;
12 static clvideo_t videoarray[ MAXCLVIDEOS ];
13 static mempool_t *cl_videomempool;
14 static rtexturepool_t *cl_videotexturepool;
16 static clvideo_t *FindUnusedVid( void )
19 for( i = 1 ; i < MAXCLVIDEOS ; i++ )
20 if( videoarray[ i ].state == CLVIDEO_UNUSED )
21 return &videoarray[ i ];
25 static qboolean OpenStream( clvideo_t * video )
28 video->stream = dpvsimpledecode_open( video->filename, &errorstring);
31 Con_Printf("unable to open \"%s\", error: %s\n", video->filename, errorstring);
37 static void SuspendVideo( clvideo_t * video )
39 if( video->suspended )
41 video->suspended = true;
43 R_FreeTexture( video->cpif.tex );
44 // free the image data
45 Mem_Free( video->imagedata );
46 // if we are in firstframe mode, also close the stream
47 if( video->state == CLVIDEO_FIRSTFRAME )
48 dpvsimpledecode_close( video->stream );
51 static qboolean WakeVideo( clvideo_t * video )
53 if( !video->suspended )
55 video->suspended = false;
57 if( video->state == CLVIDEO_FIRSTFRAME )
58 if( !OpenStream( video ) ) {
59 video->state = CLVIDEO_UNUSED;
63 video->imagedata = Mem_Alloc( cl_videomempool, video->cpif.width * video->cpif.height * cl_videobytesperpixel );
64 video->cpif.tex = R_LoadTexture2D( cl_videotexturepool, video->cpif.name,
65 video->cpif.width, video->cpif.height, NULL, TEXTYPE_RGBA, 0, NULL );
68 video->starttime += realtime - video->lasttime;
72 static clvideo_t* OpenVideo( clvideo_t *video, char *filename, char *name, int owner )
74 strncpy( video->filename, filename, MAX_QPATH );
75 video->ownertag = owner;
76 strncpy( video->cpif.name, CLVIDEOPREFIX, MAX_QPATH );
77 strncat( video->cpif.name, name, MAX_QPATH - sizeof( CLVIDEOPREFIX ) );
79 if( !OpenStream( video ) )
82 video->state = CLVIDEO_FIRSTFRAME;
84 video->framerate = dpvsimpledecode_getframerate( video->stream );
85 video->lasttime = realtime;
87 video->cpif.width = dpvsimpledecode_getwidth( video->stream );
88 video->cpif.height = dpvsimpledecode_getheight( video->stream );
89 video->cpif.tex = R_LoadTexture2D( cl_videotexturepool, video->cpif.name,
90 video->cpif.width, video->cpif.height, NULL, TEXTYPE_RGBA, 0, NULL );
92 video->imagedata = Mem_Alloc( cl_videomempool, video->cpif.width * video->cpif.height * cl_videobytesperpixel );
97 clvideo_t* CL_OpenVideo( char *filename, char *name, int owner )
101 video = FindUnusedVid();
103 Con_Printf( "unable to open video \"%s\" - video limit reached\n", filename );
106 return OpenVideo( video, filename, name, owner );
109 clvideo_t* CL_GetVideo( char *name )
114 for( i = 0 ; i < MAXCLVIDEOS ; i++ )
115 if( videoarray[ i ].state != CLVIDEO_UNUSED
116 && !strcmp( videoarray[ i ].cpif.name , name ) )
118 if( i == MAXCLVIDEOS )
120 video = &videoarray[ i ];
122 if( video->suspended )
123 if( !WakeVideo( video ) )
125 video->lasttime = realtime;
130 void CL_StartVideo( clvideo_t * video )
135 video->starttime = video->lasttime = realtime;
136 video->framenum = -1;
137 video->state = CLVIDEO_PLAY;
140 void CL_LoopVideo( clvideo_t * video )
145 video->starttime = video->lasttime = realtime;
146 video->framenum = -1;
147 video->state = CLVIDEO_LOOP;
150 void CL_PauseVideo( clvideo_t * video )
155 video->state = CLVIDEO_PAUSE;
156 video->lasttime = realtime;
159 void CL_RestartVideo( clvideo_t *video )
164 video->starttime = video->lasttime = realtime;
165 video->framenum = -1;
168 void CL_StopVideo( clvideo_t * video )
173 video->lasttime = realtime;
174 video->framenum = -1;
175 video->state = CLVIDEO_FIRSTFRAME;
178 void CL_CloseVideo( clvideo_t * video )
180 if( !video || video->state == CLVIDEO_UNUSED )
183 video->state = CLVIDEO_UNUSED;
185 if( !video->suspended || video->state != CLVIDEO_FIRSTFRAME )
186 dpvsimpledecode_close( video->stream );
187 if( !video->suspended ) {
188 Mem_Free( video->imagedata );
189 R_FreeTexture( video->cpif.tex );
193 static void VideoFrame( clvideo_t *video )
197 if( video->state == CLVIDEO_FIRSTFRAME )
200 destframe = (realtime - video->starttime) * video->framerate;
203 if( video->framenum < destframe ) {
206 if( dpvsimpledecode_video( video->stream, video->imagedata, cl_videormask,
207 cl_videogmask, cl_videobmask, cl_videobytesperpixel,
208 cl_videobytesperpixel * video->cpif.width )
210 video->framenum = -1;
211 if( video->state == CLVIDEO_LOOP )
212 video->starttime = realtime;
213 else if( video->state == CLVIDEO_PLAY )
214 video->state = CLVIDEO_FIRSTFRAME;
217 } while( video->framenum < destframe );
218 R_UpdateTexture( video->cpif.tex, video->imagedata );
222 void CL_VideoFrame( void ) // update all videos
227 for( video = videoarray, i = 0 ; i < MAXCLVIDEOS ; video++, i++ )
228 if( video->state != CLVIDEO_UNUSED && !video->suspended )
229 if( realtime - video->lasttime > CLTHRESHOLD )
230 SuspendVideo( video );
231 else if( video->state == CLVIDEO_PAUSE )
232 video->starttime = realtime + video->framenum * video->framerate;
236 if( videoarray->state == CLVIDEO_FIRSTFRAME )
240 void CL_Video_Shutdown( void )
243 for( i = 0 ; i < MAXCLVIDEOS ; i++ )
244 CL_CloseVideo( &videoarray[ i ] );
246 R_FreeTexturePool( &cl_videotexturepool );
247 Mem_FreePool( &cl_videomempool );
250 void CL_PurgeOwner( int owner )
253 for( i = 0 ; i < MAXCLVIDEOS ; i++ )
254 if( videoarray[ i ].ownertag == owner )
255 CL_CloseVideo( &videoarray[ i ] );
258 int cl_videoplaying = false; // old, but still supported
260 void CL_DrawVideo(void)
263 DrawQ_Pic(0, 0, videoarray->cpif.name, vid.conwidth, vid.conheight, 1, 1, 1, 1, 0);
266 void CL_VideoStart(char *filename)
268 if( videoarray->state != CLVIDEO_UNUSED )
269 CL_CloseVideo( videoarray );
270 if( !OpenVideo( videoarray, filename, filename, 0 ) )
273 cl_videoplaying = true;
275 CL_StartVideo( videoarray );
278 void CL_VideoStop(void)
280 cl_videoplaying = false;
282 CL_CloseVideo( videoarray );
285 static void CL_PlayVideo_f(void)
291 Con_Print("usage: playvideo <videoname>\nplays video named video/<videoname>.dpv\n");
295 sprintf(name, "video/%s.dpv", Cmd_Argv(1));
299 static void CL_StopVideo_f(void)
304 void CL_Video_Init( void )
306 cl_videobytesperpixel = 4;
307 cl_videormask = BigLong(0xFF000000);
308 cl_videogmask = BigLong(0x00FF0000);
309 cl_videobmask = BigLong(0x0000FF00);
311 cl_videomempool = Mem_AllocPool( "CL_Video", 0, NULL );
312 cl_videotexturepool = R_AllocTexturePool();
314 Cmd_AddCommand( "playvideo", CL_PlayVideo_f );
315 Cmd_AddCommand( "stopvideo", CL_StopVideo_f );