Quake II RTX doxygen  1.0 dev
cin.c File Reference
#include "client.h"
#include "client/sound/sound.h"
#include "client/sound/vorbis.h"
#include "common/files.h"
#include "refresh/images.h"

Go to the source code of this file.

Classes

struct  cblock_t
 
struct  cinematics_t
 

Functions

void SCR_StopCinematic (void)
 
void SCR_FinishCinematic (void)
 
int SmallestNode1 (int numhnodes)
 
void Huff1TableInit (void)
 
cblock_t Huff1Decompress (cblock_t in)
 
qhandle_t SCR_ReadNextFrame (void)
 
void SCR_RunCinematic (void)
 
void SCR_PlayCinematic (const char *name)
 

Variables

static cinematics_t cin = { 0 }
 
uint32_t d_8to24table [256]
 

Function Documentation

◆ Huff1Decompress()

cblock_t Huff1Decompress ( cblock_t  in)

Definition at line 206 of file cin.c.

207 {
208  byte *input;
209  byte *out_p;
210  int nodenum;
211  int count;
212  cblock_t out;
213  int inbyte;
214  int *hnodes, *hnodesbase;
215  //int i;
216 
217  // get decompressed count
218  count = in.data[0] + (in.data[1] << 8) + (in.data[2] << 16) + (in.data[3] << 24);
219  input = in.data + 4;
220  out_p = out.data = Z_Malloc(count);
221 
222  // read bits
223 
224  hnodesbase = cin.hnodes1 - 256 * 2; // nodes 0-255 aren't stored
225 
226  hnodes = hnodesbase;
227  nodenum = cin.numhnodes1[0];
228  while (count)
229  {
230  inbyte = *input++;
231  //-----------
232  if (nodenum < 256)
233  {
234  hnodes = hnodesbase + (nodenum << 9);
235  *out_p++ = nodenum;
236  if (!--count)
237  break;
238  nodenum = cin.numhnodes1[nodenum];
239  }
240  nodenum = hnodes[nodenum * 2 + (inbyte & 1)];
241  inbyte >>= 1;
242  //-----------
243  if (nodenum < 256)
244  {
245  hnodes = hnodesbase + (nodenum << 9);
246  *out_p++ = nodenum;
247  if (!--count)
248  break;
249  nodenum = cin.numhnodes1[nodenum];
250  }
251  nodenum = hnodes[nodenum * 2 + (inbyte & 1)];
252  inbyte >>= 1;
253  //-----------
254  if (nodenum < 256)
255  {
256  hnodes = hnodesbase + (nodenum << 9);
257  *out_p++ = nodenum;
258  if (!--count)
259  break;
260  nodenum = cin.numhnodes1[nodenum];
261  }
262  nodenum = hnodes[nodenum * 2 + (inbyte & 1)];
263  inbyte >>= 1;
264  //-----------
265  if (nodenum < 256)
266  {
267  hnodes = hnodesbase + (nodenum << 9);
268  *out_p++ = nodenum;
269  if (!--count)
270  break;
271  nodenum = cin.numhnodes1[nodenum];
272  }
273  nodenum = hnodes[nodenum * 2 + (inbyte & 1)];
274  inbyte >>= 1;
275  //-----------
276  if (nodenum < 256)
277  {
278  hnodes = hnodesbase + (nodenum << 9);
279  *out_p++ = nodenum;
280  if (!--count)
281  break;
282  nodenum = cin.numhnodes1[nodenum];
283  }
284  nodenum = hnodes[nodenum * 2 + (inbyte & 1)];
285  inbyte >>= 1;
286  //-----------
287  if (nodenum < 256)
288  {
289  hnodes = hnodesbase + (nodenum << 9);
290  *out_p++ = nodenum;
291  if (!--count)
292  break;
293  nodenum = cin.numhnodes1[nodenum];
294  }
295  nodenum = hnodes[nodenum * 2 + (inbyte & 1)];
296  inbyte >>= 1;
297  //-----------
298  if (nodenum < 256)
299  {
300  hnodes = hnodesbase + (nodenum << 9);
301  *out_p++ = nodenum;
302  if (!--count)
303  break;
304  nodenum = cin.numhnodes1[nodenum];
305  }
306  nodenum = hnodes[nodenum * 2 + (inbyte & 1)];
307  inbyte >>= 1;
308  //-----------
309  if (nodenum < 256)
310  {
311  hnodes = hnodesbase + (nodenum << 9);
312  *out_p++ = nodenum;
313  if (!--count)
314  break;
315  nodenum = cin.numhnodes1[nodenum];
316  }
317  nodenum = hnodes[nodenum * 2 + (inbyte & 1)];
318  inbyte >>= 1;
319  }
320 
321  if (input - in.data != in.count && input - in.data != in.count + 1)
322  {
323  Com_Printf("Decompression overread by %i", (input - in.data) - in.count);
324  }
325  out.count = out_p - out.data;
326 
327  return out;
328 }

Referenced by SCR_ReadNextFrame().

◆ Huff1TableInit()

void Huff1TableInit ( void  )

Definition at line 155 of file cin.c.

156 {
157  int prev;
158  int j;
159  int *node, *nodebase;
160  byte counts[256];
161  int numhnodes;
162 
163  cin.hnodes1 = Z_Malloc(256 * 256 * 2 * 4);
164  memset(cin.hnodes1, 0, 256 * 256 * 2 * 4);
165 
166  for (prev = 0; prev < 256; prev++)
167  {
168  memset(cin.h_count, 0, sizeof(cin.h_count));
169  memset(cin.h_used, 0, sizeof(cin.h_used));
170 
171  // read a row of counts
172  FS_Read(counts, sizeof(counts), cin.file);
173  for (j = 0; j < 256; j++)
174  cin.h_count[j] = counts[j];
175 
176  // build the nodes
177  numhnodes = 256;
178  nodebase = cin.hnodes1 + prev * 256 * 2;
179 
180  while (numhnodes != 511)
181  {
182  node = nodebase + (numhnodes - 256) * 2;
183 
184  // pick two lowest counts
185  node[0] = SmallestNode1(numhnodes);
186  if (node[0] == -1)
187  break; // no more
188 
189  node[1] = SmallestNode1(numhnodes);
190  if (node[1] == -1)
191  break;
192 
193  cin.h_count[numhnodes] = cin.h_count[node[0]] + cin.h_count[node[1]];
194  numhnodes++;
195  }
196 
197  cin.numhnodes1[prev] = numhnodes - 1;
198  }
199 }

Referenced by SCR_PlayCinematic().

◆ SCR_FinishCinematic()

void SCR_FinishCinematic ( void  )

Definition at line 105 of file cin.c.

106 {
108 
109  // tell the server to advance to the next map / cinematic
110  CL_ClientCommand(va("nextserver %i\n", cl.servercount));
111 }

Referenced by Key_Event(), SCR_PlayCinematic(), and SCR_RunCinematic().

◆ SCR_PlayCinematic()

void SCR_PlayCinematic ( const char *  name)

Definition at line 477 of file cin.c.

478 {
479  int width, height;
480  int old_khz;
481 
482  // make sure CD isn't playing music
483  OGG_Stop();
484 
485  cin.s_khz_original = 0;
486 
487  cin.frame_index = 0;
488  cin.start_time = 0;
489 
490  if (!COM_CompareExtension(name, ".pcx"))
491  {
492  cl.image_precache[0] = R_RegisterPic2(name);
493  if (!cl.image_precache[0]) {
495  return;
496  }
497  }
498  else if (!COM_CompareExtension(name, ".cin"))
499  {
500  if (!Cvar_VariableValue("cl_cinematics"))
501  {
503  return;
504  }
505 
506  Q_snprintf(cin.file_name, sizeof(cin.file_name), "video/%s", name);
507 
508  FS_FOpenFile(cin.file_name, &cin.file, FS_MODE_READ);
509  if (!cin.file)
510  {
511  Com_WPrintf("Cinematic \"%s\" not found. Skipping.\n", name);
513  return;
514  }
515 
516  FS_Read(&width, 4, cin.file);
517  FS_Read(&height, 4, cin.file);
518  cin.width = LittleLong(width);
519  cin.height = LittleLong(height);
520 
521  FS_Read(&cin.s_rate, 4, cin.file);
522  cin.s_rate = LittleLong(cin.s_rate);
523  FS_Read(&cin.s_width, 4, cin.file);
524  cin.s_width = LittleLong(cin.s_width);
525  FS_Read(&cin.s_channels, 4, cin.file);
526  cin.s_channels = LittleLong(cin.s_channels);
527 
528  Huff1TableInit();
529 
530  cin.palette_active = qfalse;
531 
532  // switch to 22 khz sound if necessary
533  old_khz = Cvar_VariableValue("s_khz");
534  if (old_khz != cin.s_rate / 1000 && s_started == SS_DMA)
535  {
536  cin.s_khz_original = old_khz;
537  Cvar_Set("s_khz", va("%d", cin.s_rate / 1000));
538  }
539 
540  cin.frame_index = 0;
543  }
544  else
545  {
547  return;
548  }
549 
551 
552  SCR_EndLoadingPlaque(); // get rid of loading plaque
553  Con_Close(qfalse); // get rid of connection screen
554 }

Referenced by CL_ParseServerData().

◆ SCR_ReadNextFrame()

qhandle_t SCR_ReadNextFrame ( void  )

Definition at line 337 of file cin.c.

338 {
339  int r;
340  int command;
341  byte samples[22050 / 14 * 4];
342  byte compressed[0x20000];
343  int size;
344  byte *pic;
345  cblock_t in, huf1;
346  int start, end, count;
347 
348  // read the next frame
349  r = FS_Read(&command, 4, cin.file);
350  if (r == 0) // we'll give it one more chance
351  r = FS_Read(&command, 4, cin.file);
352 
353  if (r != 4)
354  return 0;
355  command = LittleLong(command);
356  if (command == 2)
357  return 0; // last frame marker
358 
359  if (command == 1)
360  { // read palette
361  FS_Read(cin.palette, sizeof(cin.palette), cin.file);
362  cin.palette_active = qtrue;
363  }
364 
365  // decompress the next frame
366  FS_Read(&size, 4, cin.file);
367  size = LittleLong(size);
368  if (size > sizeof(compressed) || size < 1)
369  Com_Error(ERR_DROP, "Bad compressed frame size");
370  FS_Read(compressed, size, cin.file);
371 
372  // read sound
373  start = cin.frame_index*cin.s_rate / 14;
374  end = (cin.frame_index + 1)*cin.s_rate / 14;
375  count = end - start;
376 
378 
380 
381  in.data = compressed;
382  in.count = size;
383 
384  huf1 = Huff1Decompress(in);
385 
386  pic = huf1.data;
387 
388  uint32_t* rgba = Z_Malloc(cin.width * cin.height * 4);
389  uint32_t* wptr = rgba;
390 
391  for (int y = 0; y < cin.height; y++)
392  {
393  if (cin.palette_active)
394  {
395  for (int x = 0; x < cin.width; x++)
396  {
397  byte* src = cin.palette + (*pic) * 3;
398  *wptr = MakeColor(src[0], src[1], src[2], 255);
399  pic++;
400  wptr++;
401  }
402  }
403  else
404  {
405  for (int x = 0; x < cin.width; x++)
406  {
407  *wptr = d_8to24table[*pic];
408  pic++;
409  wptr++;
410  }
411  }
412  }
413 
414  Z_Free(huf1.data);
415 
416  cin.frame_index++;
417 
418  const char* image_name = va("%s[%d]", cin.file_name, cin.frame_index);
419  return R_RegisterRawImage(image_name, cin.width, cin.height, (byte*)rgba, IT_SPRITE, IF_SRGB);
420 }

Referenced by SCR_PlayCinematic(), and SCR_RunCinematic().

◆ SCR_RunCinematic()

void SCR_RunCinematic ( void  )

Definition at line 429 of file cin.c.

430 {
431  int frame;
432 
433  if (cin.start_time <= 0)
434  return;
435 
436  if (cin.frame_index == -1)
437  return; // static image
438 
439  if (cls.key_dest != KEY_GAME)
440  {
441  // pause if menu or console is up
442  cin.start_time = cls.realtime - cin.frame_index * 1000 / 14;
443 
445 
446  return;
447  }
448 
449  frame = (cls.realtime - cin.start_time)*14.0 / 1000;
450  if (frame <= cin.frame_index)
451  return;
452  if (frame > cin.frame_index + 1)
453  {
454  // Com_Printf("Dropped frame: %i > %i\n", frame, cin.frame_index + 1);
455  cin.start_time = cls.realtime - cin.frame_index * 1000 / 14;
456  }
457 
460 
461  if (!cl.image_precache[0])
462  {
464  cin.start_time = 1; // hack to get the black screen behind loading
466  cin.start_time = 0;
467  return;
468  }
469 }

Referenced by CL_Frame().

◆ SCR_StopCinematic()

void SCR_StopCinematic ( void  )

Definition at line 67 of file cin.c.

68 {
69  cin.start_time = 0; // done
70 
72 
73  if (cl.image_precache[0])
74  {
76  cl.image_precache[0] = 0;
77  }
78 
79  if (cin.file)
80  {
82  cin.file = 0;
83  }
84  if (cin.hnodes1)
85  {
87  cin.hnodes1 = NULL;
88  }
89 
90  // switch the sample rate back to its original value if necessary
91  if (cin.s_khz_original != 0)
92  {
93  Cvar_Set("s_khz", va("%d", cin.s_khz_original));
94  cin.s_khz_original = 0;
95  }
96 }

Referenced by SCR_FinishCinematic().

◆ SmallestNode1()

int SmallestNode1 ( int  numhnodes)

Definition at line 120 of file cin.c.

121 {
122  int i;
123  int best, bestnode;
124 
125  best = 99999999;
126  bestnode = -1;
127  for (i = 0; i < numhnodes; i++)
128  {
129  if (cin.h_used[i])
130  continue;
131  if (!cin.h_count[i])
132  continue;
133  if (cin.h_count[i] < best)
134  {
135  best = cin.h_count[i];
136  bestnode = i;
137  }
138  }
139 
140  if (bestnode == -1)
141  return -1;
142 
143  cin.h_used[bestnode] = qtrue;
144  return bestnode;
145 }

Referenced by Huff1TableInit().

Variable Documentation

◆ cin

◆ d_8to24table

R_RegisterRawImage
qhandle_t R_RegisterRawImage(const char *name, int width, int height, byte *pic, imagetype_t type, imageflags_t flags)
Definition: images.c:1228
Cvar_Set
cvar_t * Cvar_Set(const char *var_name, const char *value)
Definition: cvar.c:466
cinematics_t::frame_index
int frame_index
Definition: cin.c:57
client_state_s::image_precache
qhandle_t image_precache[MAX_IMAGES]
Definition: client.h:306
cinematics_t::start_time
int start_time
Definition: cin.c:56
height
static int height
Definition: physical_sky.c:39
SCR_StopCinematic
void SCR_StopCinematic(void)
Definition: cin.c:67
Q_snprintf
size_t Q_snprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:846
FS_Read
ssize_t FS_Read(void *buf, size_t len, qhandle_t f)
Definition: files.c:1547
cinematics_t::palette
byte palette[768]
Definition: cin.c:50
input
static in_state_t input
Definition: input.c:71
client_static_s::key_dest
keydest_t key_dest
Definition: client.h:376
cinematics_t::s_channels
int s_channels
Definition: cin.c:38
client_static_s::state
connstate_t state
Definition: client.h:375
d_8to24table
uint32_t d_8to24table[256]
Definition: images.c:654
cinematics_t::numhnodes1
int numhnodes1[256]
Definition: cin.c:45
SCR_EndLoadingPlaque
void SCR_EndLoadingPlaque(void)
Definition: screen.c:1456
client_state_s::servercount
int servercount
Definition: client.h:276
width
static int width
Definition: physical_sky.c:38
cinematics_t::height
int height
Definition: cin.c:41
FS_FOpenFile
ssize_t FS_FOpenFile(const char *name, qhandle_t *f, unsigned mode)
Definition: files.c:1692
cinematics_t::file_name
char file_name[MAX_QPATH]
Definition: cin.c:53
Com_Error
void Com_Error(error_type_t type, const char *fmt,...)
Definition: g_main.c:258
S_UnqueueRawSamples
void S_UnqueueRawSamples()
Definition: mix.c:400
cinematics_t::s_khz_original
int s_khz_original
Definition: cin.c:35
cinematics_t::s_width
int s_width
Definition: cin.c:37
SCR_FinishCinematic
void SCR_FinishCinematic(void)
Definition: cin.c:105
Huff1Decompress
cblock_t Huff1Decompress(cblock_t in)
Definition: cin.c:206
va
char * va(const char *format,...)
Definition: shared.c:429
Z_Free
void Z_Free(void *ptr)
Definition: zone.c:147
SmallestNode1
int SmallestNode1(int numhnodes)
Definition: cin.c:120
cinematics_t::width
int width
Definition: cin.c:40
Con_Close
void Con_Close(qboolean force)
Definition: console.c:124
cin
static cinematics_t cin
Definition: cin.c:60
SCR_ReadNextFrame
qhandle_t SCR_ReadNextFrame(void)
Definition: cin.c:337
cl
client_state_t cl
Definition: main.c:99
cinematics_t::hnodes1
int * hnodes1
Definition: cin.c:44
cinematics_t::file
qhandle_t file
Definition: cin.c:54
cls
client_static_t cls
Definition: main.c:98
ca_cinematic
@ ca_cinematic
Definition: client.h:341
cinematics_t::palette_active
qboolean palette_active
Definition: cin.c:51
OGG_Stop
void OGG_Stop(void)
Definition: ogg.c:488
cinematics_t::h_count
int h_count[512]
Definition: cin.c:48
cinematics_t::s_rate
int s_rate
Definition: cin.c:36
cblock_t::data
byte * data
Definition: cin.c:29
Huff1TableInit
void Huff1TableInit(void)
Definition: cin.c:155
R_UnregisterImage
void R_UnregisterImage(qhandle_t handle)
Definition: images.c:1270
cblock_t
Definition: cin.c:27
samples
unsigned samples[LAG_WIDTH]
Definition: screen.c:528
cblock_t::count
int count
Definition: cin.c:30
client_static_s::realtime
unsigned realtime
Definition: client.h:389
SCR_BeginLoadingPlaque
void SCR_BeginLoadingPlaque(void)
Definition: screen.c:1424
CL_ClientCommand
void CL_ClientCommand(const char *string)
Definition: main.c:299
FS_FCloseFile
void FS_FCloseFile(qhandle_t f)
Definition: files.c:759
Cvar_VariableValue
float Cvar_VariableValue(const char *var_name)
Definition: cvar.c:89
s_started
sndstarted_t s_started
Definition: main.c:32
cinematics_t::h_used
int h_used[512]
Definition: cin.c:47
S_RawSamples
void S_RawSamples(int samples, int rate, int width, int channels, byte *data, float volume)
Definition: mix.c:303