635 lines · 11.9 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <stdio.h>#include "dat.h"#include "fns.h" typedef struct{	byte	*data;	int		count;} cblock_t; typedef struct{	qboolean	restart_sound;	int		s_rate;	int		s_width;	int		s_channels; 	int		width;	int		height;	byte	*pic;	byte	*pic_pending; 	// order 1 huffman stuff	int		*hnodes1;	// [256][256][2];	int		numhnodes1[256]; 	int		h_used[512];	int		h_count[512];} cinematics_t; cinematics_t	cin; /*================================================================= PCX LOADING =================================================================*/  /*==============SCR_LoadPCX==============*/void SCR_LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height){	byte	*raw;	pcx_t	*pcx;	int		x, y;	int		len;	int		dataByte, runLength;	byte	*out, *pix; 	*pic = NULL; 	//	// load the file	//	len = FS_LoadFile (filename, (void **)&raw);	if (!raw)		return;	// Com_Printf ("Bad pcx file %s\n", filename); 	//	// parse the PCX file	//	pcx = (pcx_t *)raw;	raw = &pcx->data; 	if (pcx->manufacturer != 0x0a		|| pcx->version != 5		|| pcx->encoding != 1		|| pcx->bits_per_pixel != 8		|| pcx->xmax >= 640		|| pcx->ymax >= 480)	{		Com_Printf ("Bad pcx file %s\n", filename);		return;	} 	out = Z_Malloc ( (pcx->ymax+1) * (pcx->xmax+1) ); 	*pic = out; 	pix = out; 	if (palette)	{		*palette = Z_Malloc(768);		memcpy (*palette, (byte *)pcx + len - 768, 768);	} 	if (width)		*width = pcx->xmax+1;	if (height)		*height = pcx->ymax+1; 	for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)	{		for (x=0 ; x<=pcx->xmax ; )		{			dataByte = *raw++; 			if((dataByte & 0xC0) == 0xC0)			{				runLength = dataByte & 0x3F;				dataByte = *raw++;			}			else				runLength = 1; 			while(runLength-- > 0)				pix[x++] = dataByte;		} 	} 	if ( raw - (byte *)pcx > len)	{		Com_Printf ("PCX file %s was malformed", filename);		Z_Free (*pic);		*pic = NULL;	} 	FS_FreeFile (pcx);} //============================================================= /*==================SCR_StopCinematic==================*/void SCR_StopCinematic (void){	cl.cinematictime = 0;	// done	if (cin.pic)	{		Z_Free (cin.pic);		cin.pic = NULL;	}	if (cin.pic_pending)	{		Z_Free (cin.pic_pending);		cin.pic_pending = NULL;	}	if (cl.cinematicpalette_active)	{		re.CinematicSetPalette(NULL);		cl.cinematicpalette_active = false;	}	if (cl.cinematic_file)	{		fclose (cl.cinematic_file);		cl.cinematic_file = NULL;	}	if (cin.hnodes1)	{		Z_Free (cin.hnodes1);		cin.hnodes1 = NULL;	} 	// switch back down to 11 khz sound if necessary	if (cin.restart_sound)	{		cin.restart_sound = false;		restartsnd();	} } /*====================SCR_FinishCinematic Called when either the cinematic completes, or it is aborted====================*/void SCR_FinishCinematic (void){	// tell the server to advance to the next map / cinematic	MSG_WriteByte (&cls.netchan.message, clc_stringcmd);	SZ_Print (&cls.netchan.message, va("nextserver %i\n", cl.servercount));} //========================================================================== /*==================SmallestNode1==================*/int	SmallestNode1 (int numhnodes){	int		i;	int		best, bestnode; 	best = 99999999;	bestnode = -1;	for (i=0 ; i<numhnodes ; i++)	{		if (cin.h_used[i])			continue;		if (!cin.h_count[i])			continue;		if (cin.h_count[i] < best)		{			best = cin.h_count[i];			bestnode = i;		}	} 	if (bestnode == -1)		return -1; 	cin.h_used[bestnode] = true;	return bestnode;}  /*==================Huff1TableInit Reads the 64k counts table and initializes the node trees==================*/void Huff1TableInit (void){	int		prev;	int		j;	int		*node, *nodebase;	byte	counts[256];	int		numhnodes; 	cin.hnodes1 = Z_Malloc (256*256*2*4);	memset (cin.hnodes1, 0, 256*256*2*4); 	for (prev=0 ; prev<256 ; prev++)	{		memset (cin.h_count,0,sizeof(cin.h_count));		memset (cin.h_used,0,sizeof(cin.h_used)); 		// read a row of counts		FS_Read (counts, sizeof(counts), cl.cinematic_file);		for (j=0 ; j<256 ; j++)			cin.h_count[j] = counts[j]; 		// build the nodes		numhnodes = 256;		nodebase = cin.hnodes1 + prev*256*2; 		while (numhnodes != 511)		{			node = nodebase + (numhnodes-256)*2; 			// pick two lowest counts			node[0] = SmallestNode1 (numhnodes);			if (node[0] == -1)				break;	// no more 			node[1] = SmallestNode1 (numhnodes);			if (node[1] == -1)				break; 			cin.h_count[numhnodes] = cin.h_count[node[0]] + cin.h_count[node[1]];			numhnodes++;		} 		cin.numhnodes1[prev] = numhnodes-1;	}} /*==================Huff1Decompress==================*/cblock_t Huff1Decompress (cblock_t in){	byte		*input;	byte		*out_p;	int			nodenum;	int			count;	cblock_t	out;	int			inbyte;	int			*hnodes, *hnodesbase;//int		i; 	// get decompressed count	count = in.data[0] + (in.data[1]<<8) + (in.data[2]<<16) + (in.data[3]<<24);	input = in.data + 4;	out_p = out.data = Z_Malloc (count); 	// read bits 	hnodesbase = cin.hnodes1 - 256*2;	// nodes 0-255 aren't stored 	hnodes = hnodesbase;	nodenum = cin.numhnodes1[0];	while (count)	{		inbyte = *input++;		//-----------		if (nodenum < 256)		{			hnodes = hnodesbase + (nodenum<<9);			*out_p++ = nodenum;			if (!--count)				break;			nodenum = cin.numhnodes1[nodenum];		}		nodenum = hnodes[nodenum*2 + (inbyte&1)];		inbyte >>=1;		//-----------		if (nodenum < 256)		{			hnodes = hnodesbase + (nodenum<<9);			*out_p++ = nodenum;			if (!--count)				break;			nodenum = cin.numhnodes1[nodenum];		}		nodenum = hnodes[nodenum*2 + (inbyte&1)];		inbyte >>=1;		//-----------		if (nodenum < 256)		{			hnodes = hnodesbase + (nodenum<<9);			*out_p++ = nodenum;			if (!--count)				break;			nodenum = cin.numhnodes1[nodenum];		}		nodenum = hnodes[nodenum*2 + (inbyte&1)];		inbyte >>=1;		//-----------		if (nodenum < 256)		{			hnodes = hnodesbase + (nodenum<<9);			*out_p++ = nodenum;			if (!--count)				break;			nodenum = cin.numhnodes1[nodenum];		}		nodenum = hnodes[nodenum*2 + (inbyte&1)];		inbyte >>=1;		//-----------		if (nodenum < 256)		{			hnodes = hnodesbase + (nodenum<<9);			*out_p++ = nodenum;			if (!--count)				break;			nodenum = cin.numhnodes1[nodenum];		}		nodenum = hnodes[nodenum*2 + (inbyte&1)];		inbyte >>=1;		//-----------		if (nodenum < 256)		{			hnodes = hnodesbase + (nodenum<<9);			*out_p++ = nodenum;			if (!--count)				break;			nodenum = cin.numhnodes1[nodenum];		}		nodenum = hnodes[nodenum*2 + (inbyte&1)];		inbyte >>=1;		//-----------		if (nodenum < 256)		{			hnodes = hnodesbase + (nodenum<<9);			*out_p++ = nodenum;			if (!--count)				break;			nodenum = cin.numhnodes1[nodenum];		}		nodenum = hnodes[nodenum*2 + (inbyte&1)];		inbyte >>=1;		//-----------		if (nodenum < 256)		{			hnodes = hnodesbase + (nodenum<<9);			*out_p++ = nodenum;			if (!--count)				break;			nodenum = cin.numhnodes1[nodenum];		}		nodenum = hnodes[nodenum*2 + (inbyte&1)];	} 	if (input - in.data != in.count && input - in.data != in.count+1)	{		Com_Printf ("Decompression overread by %i", (input - in.data) - in.count);	}	out.count = out_p - out.data; 	return out;} /*==================SCR_ReadNextFrame==================*/byte *SCR_ReadNextFrame (void){	int		r;	int		command;	byte	samples[22050/14*4];	byte	compressed[0x20000];	int		size;	byte	*pic;	cblock_t	in, huf1;	int		start, end, count; 	// read the next frame	r = fread (&command, 4, 1, cl.cinematic_file);	if (r == 0)		// we'll give it one more chance		r = fread (&command, 4, 1, cl.cinematic_file); 	if (r != 1)		return NULL;	command = LittleLong(command);	if (command == 2)		return NULL;	// last frame marker 	if (command == 1)	{	// read palette		FS_Read (cl.cinematicpalette, sizeof(cl.cinematicpalette), cl.cinematic_file);		cl.cinematicpalette_active=0;	// dubious....  exposes an edge case	} 	// decompress the next frame	FS_Read (&size, 4, cl.cinematic_file);	size = LittleLong(size);	if (size > sizeof(compressed) || size < 1)		Com_Error (ERR_DROP, "Bad compressed frame size");	FS_Read (compressed, size, cl.cinematic_file); 	// read sound	start = cl.cinematicframe*cin.s_rate/14;	end = (cl.cinematicframe+1)*cin.s_rate/14;	count = end - start; 	FS_Read (samples, count*cin.s_width*cin.s_channels, cl.cinematic_file); 	S_RawSamples (count, cin.s_rate, cin.s_width, cin.s_channels, samples); 	in.data = compressed;	in.count = size; 	huf1 = Huff1Decompress (in); 	pic = huf1.data; 	cl.cinematicframe++; 	return pic;}  /*==================SCR_RunCinematic ==================*/void SCR_RunCinematic (void){	int		frame; 	if (cl.cinematictime <= 0)	{		SCR_StopCinematic ();		return;	} 	if (cl.cinematicframe == -1)		return;		// static image 	if (cls.key_dest != key_game)	{	// pause if menu or console is up		cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14;		return;	} 	frame = (cls.realtime - cl.cinematictime)*14.0/1000;	if (frame <= cl.cinematicframe)		return;	if (frame > cl.cinematicframe+1)	{		Com_Printf ("Dropped frame: %i > %i\n", frame, cl.cinematicframe+1);		cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14;	}

Lines 1–500 of 635.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t