more tolerance to deviations in calculated plane distances compared to the stored...
[divverent/darkplaces.git] / cl_video.c
1
2 #include "quakedef.h"
3 #include "cl_video.h"
4 #include "dpvsimpledecode.h"
5
6 mempool_t *clvideomempool;
7
8 int cl_videoplaying = false;
9 void *cl_videostream;
10
11 double cl_videostarttime;
12 int cl_videoframenum;
13 double cl_videoframerate;
14
15 int cl_videoimagewidth;
16 int cl_videoimageheight;
17 int cl_videoimagedata_rmask;
18 int cl_videoimagedata_gmask;
19 int cl_videoimagedata_bmask;
20 int cl_videoimagedata_bytesperpixel;
21 void *cl_videoimagedata;
22
23 rtexture_t *cl_videotexture;
24 rtexturepool_t *cl_videotexturepool;
25
26 void CL_VideoFrame(void)
27 {
28         int frames, framenum;
29         if (!cl_videoplaying)
30                 return;
31         framenum = (realtime - cl_videostarttime) * cl_videoframerate;
32         //Con_Printf("frame %i\n", framenum);
33         if (framenum < 0)
34                 framenum = 0;
35         frames = 0;
36         while (cl_videoframenum < framenum)
37         {
38                 frames++;
39                 cl_videoframenum++;
40                 if (dpvsimpledecode_video(cl_videostream, cl_videoimagedata, cl_videoimagedata_rmask, cl_videoimagedata_gmask, cl_videoimagedata_bmask, cl_videoimagedata_bytesperpixel, cl_videoimagewidth * cl_videoimagedata_bytesperpixel))
41                 {
42                         CL_VideoStop();
43                         return;
44                 }
45         }
46         if (frames)
47         {
48                 R_UpdateTexture(cl_videotexture, cl_videoimagedata);
49                 //Draw_NewPic("engine_videoframe", cl_videoimagewidth, cl_videoimageheight, false, cl_videoimagedata);
50         }
51 }
52
53 void CL_DrawVideo(void)
54 {
55         if (cl_videoplaying)
56         {
57                 drawqueuemesh_t mesh;
58                 float vertex3f[12];
59                 float texcoord2f[8];
60                 float color4f[16];
61                 float s1, t1, s2, t2, x1, y1, x2, y2;
62                 x1 = 0;
63                 y1 = 0;
64                 x2 = vid.conwidth;
65                 y2 = vid.conheight;
66                 R_FragmentLocation(cl_videotexture, NULL, NULL, &s1, &t1, &s2, &t2);
67                 texcoord2f[0] = s1;texcoord2f[1] = t1;
68                 texcoord2f[2] = s2;texcoord2f[3] = t1;
69                 texcoord2f[4] = s2;texcoord2f[5] = t2;
70                 texcoord2f[6] = s1;texcoord2f[7] = t2;
71                 R_FillColors(color4f, 4, 1, 1, 1, 1);
72                 vertex3f[ 0] = x1;vertex3f[ 1] = y1;vertex3f[ 2] = 0;
73                 vertex3f[ 3] = x2;vertex3f[ 4] = y1;vertex3f[ 5] = 0;
74                 vertex3f[ 6] = x2;vertex3f[ 7] = y2;vertex3f[ 8] = 0;
75                 vertex3f[ 9] = x1;vertex3f[10] = y2;vertex3f[11] = 0;
76                 mesh.texture = cl_videotexture;
77                 mesh.num_triangles = 2;
78                 mesh.num_vertices = 4;
79                 mesh.data_element3i = polygonelements;
80                 mesh.data_vertex3f = vertex3f;
81                 mesh.data_texcoord2f = texcoord2f;
82                 mesh.data_color4f = color4f;
83                 DrawQ_Mesh(&mesh, 0);
84                 //DrawQ_Pic(0, 0, "engine_videoframe", vid.conwidth, vid.conheight, 1, 1, 1, 1, 0);
85         }
86 }
87
88 void CL_VideoStart(char *filename)
89 {
90         char *errorstring;
91         cl_videostream = dpvsimpledecode_open(filename, &errorstring);
92         if (!cl_videostream)
93         {
94                 Con_Printf("unable to open \"%s\", error: %s\n", filename, errorstring);
95                 return;
96         }
97
98         cl_videoplaying = true;
99         cl_videostarttime = realtime;
100         cl_videoframenum = -1;
101         cl_videoframerate = dpvsimpledecode_getframerate(cl_videostream);
102         cl_videoimagewidth = dpvsimpledecode_getwidth(cl_videostream);
103         cl_videoimageheight = dpvsimpledecode_getheight(cl_videostream);
104
105         // RGBA format
106         cl_videoimagedata_bytesperpixel = 4;
107         cl_videoimagedata_rmask = BigLong(0xFF000000);
108         cl_videoimagedata_gmask = BigLong(0x00FF0000);
109         cl_videoimagedata_bmask = BigLong(0x0000FF00);
110         cl_videoimagedata = Mem_Alloc(clvideomempool, cl_videoimagewidth * cl_videoimageheight * cl_videoimagedata_bytesperpixel);
111         //memset(cl_videoimagedata, 97, cl_videoimagewidth * cl_videoimageheight * cl_videoimagedata_bytesperpixel);
112
113         cl_videotexturepool = R_AllocTexturePool();
114         cl_videotexture = R_LoadTexture2D(cl_videotexturepool, "videotexture", cl_videoimagewidth, cl_videoimageheight, NULL, TEXTYPE_RGBA, TEXF_FRAGMENT, NULL);
115 }
116
117 void CL_VideoStop(void)
118 {
119         cl_videoplaying = false;
120
121         if (cl_videostream)
122                 dpvsimpledecode_close(cl_videostream);
123         cl_videostream = NULL;
124
125         if (cl_videoimagedata)
126                 Mem_Free(cl_videoimagedata);
127         cl_videoimagedata = NULL;
128
129         cl_videotexture = NULL;
130         R_FreeTexturePool(&cl_videotexturepool);
131
132         Draw_FreePic("engine_videoframe");
133 }
134
135 static void CL_PlayVideo_f(void)
136 {
137         char name[1024];
138
139         if (Cmd_Argc() != 2)
140         {
141                 Con_Print("usage: playvideo <videoname>\nplays video named video/<videoname>.dpv\n");
142                 return;
143         }
144
145         sprintf(name, "video/%s.dpv", Cmd_Argv(1));
146         CL_VideoStart(name);
147 }
148
149 static void CL_StopVideo_f(void)
150 {
151         CL_VideoStop();
152 }
153
154 void CL_Video_Init(void)
155 {
156         Cmd_AddCommand("playvideo", CL_PlayVideo_f);
157         Cmd_AddCommand("stopvideo", CL_StopVideo_f);
158
159         clvideomempool = Mem_AllocPool("CL_Video", 0, NULL);
160 }