Пример #1
0
/*
 * ============
 * Cache_TryAlloc
 *
 * Looks for a free block of memory between the high and low hunk marks
 * Size should already include the header and padding
 * ============
 */
static cache_system_t *
Cache_TryAlloc(int size, qboolean nobottom)
{
    cache_system_t *cs, *newobj;

    /* is the cache completely empty? */
    if (!nobottom && cache_head.prev == &cache_head) {
	if (hunk_size - hunk_high_used - hunk_low_used < size)
	    Sys_Error("%s: %i is greater than free hunk", __func__, size);

	newobj = (cache_system_t *)(hunk_base + hunk_low_used);
	memset(newobj, 0, sizeof(*newobj));
	newobj->size = size;

	cache_head.prev = cache_head.next = newobj;
	newobj->prev = newobj->next = &cache_head;

	Cache_MakeLRU(newobj);
	return newobj;
    }

    /* search from the bottom up for space */
    newobj = (cache_system_t *)(hunk_base + hunk_low_used);
    cs = cache_head.next;

    do {
	if (!nobottom || cs != cache_head.next) {
	    if ((byte *)cs - (byte *)newobj >= size) {	/* found space */
		memset(newobj, 0, sizeof(*newobj));
		newobj->size = size;

		newobj->next = cs;
		newobj->prev = cs->prev;
		cs->prev->next = newobj;
		cs->prev = newobj;

		Cache_MakeLRU(newobj);

		return newobj;
	    }
	}

	/* continue looking */
	newobj = (cache_system_t *)((byte *)cs + cs->size);
	cs = cs->next;

    } while (cs != &cache_head);

    /* try to allocate one at the very end */
    if (hunk_base + hunk_size - hunk_high_used - (byte *)newobj >= size) {
	memset(newobj, 0, sizeof(*newobj));
	newobj->size = size;

	newobj->next = &cache_head;
	newobj->prev = cache_head.prev;
	cache_head.prev->next = newobj;
	cache_head.prev = newobj;

	Cache_MakeLRU(newobj);

	return newobj;
    }

    return NULL;		/* couldn't allocate */
}
Пример #2
0
/*
================
R_DrawSolidClippedSubmodelPolygons
================
*/
void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel)
{
	int			i, j, lindex;
	vec_t		dot;
	msurface_t	*psurf;
	int			numsurfaces;
	mplane_t	*pplane;
	mvertex_t	bverts[MAX_BMODEL_VERTS];
	bedge_t		bedges[MAX_BMODEL_EDGES], *pbedge;
	medge_t		*pedge, *pedges;

// FIXME: use bounding-box-based frustum clipping info?

	psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
	numsurfaces = pmodel->nummodelsurfaces;
	pedges = pmodel->edges;

	for (i=0 ; i<numsurfaces ; i++, psurf++)
	{
	// find which side of the node we are on
		pplane = psurf->plane;

		dot = DotProduct (modelorg, pplane->normal) - pplane->dist;

	// draw the polygon
		if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
			(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
		{
		// FIXME: use bounding-box-based frustum clipping info?

		// copy the edges to bedges, flipping if necessary so always
		// clockwise winding
		// FIXME: if edges and vertices get caches, these assignments must move
		// outside the loop, and overflow checking must be done here
			pbverts = bverts;
			pbedges = bedges;
			numbverts = numbedges = 0;

			if (psurf->numedges > 0)
			{
				pbedge = &bedges[numbedges];
				numbedges += psurf->numedges;

				for (j=0 ; j<psurf->numedges ; j++)
				{
				   lindex = pmodel->surfedges[psurf->firstedge+j];

					if (lindex > 0)
					{
						pedge = &pedges[lindex];
						pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]];
						pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]];
					}
					else
					{
						lindex = -lindex;
						pedge = &pedges[lindex];
						pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]];
						pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]];
					}

					pbedge[j].pnext = &pbedge[j+1];
				}

				pbedge[j-1].pnext = NULL;	// mark end of edges

				R_RecursiveClipBPoly (pbedge, currententity->topnode, psurf);
			}
			else
			{
				Sys_Error ("no edges in bmodel");
			}
		}
	}
}
Пример #3
0
/**
 * @brief Writes the brush list to the bsp
 */
void EmitBrushes (void)
{
	curTile->numbrushsides = 0;
	curTile->numbrushes = nummapbrushes;
	/* Clear out curTile->brushes */
	OBJZERO(curTile->brushes);

	for (int bnum = 0; bnum < nummapbrushes; bnum++) {
		const mapbrush_t* b = &mapbrushes[bnum];
		dBspBrush_t* db = &curTile->dbrushes[bnum];
		cBspBrush_t* cb = &curTile->brushes[bnum];

		db->brushContentFlags = b->contentFlags;
		db->firstbrushside = curTile->numbrushsides;
		db->numsides = b->numsides;
		cb->brushContentFlags = b->contentFlags;
		cb->firstbrushside = curTile->numbrushsides;
		cb->numsides = b->numsides;
		cb->checkcount = 0;
		for (int j = 0; j < b->numsides; j++) {
			if (curTile->numbrushsides == MAX_MAP_BRUSHSIDES) {
				Sys_Error("MAX_MAP_BRUSHSIDES (%i)", curTile->numbrushsides);
			} else {
				dBspBrushSide_t* cp = &curTile->brushsides[curTile->numbrushsides];
				curTile->numbrushsides++;
				cp->planenum = b->original_sides[j].planenum;
				cp->texinfo = b->original_sides[j].texinfo;
			}
		}

		/* add any axis planes not contained in the brush to bevel off corners */
		for (int x = 0; x < 3; x++)
			for (int s = -1; s <= 1; s += 2) {
				/* add the plane */
				vec3_t normal;
				VectorCopy(vec3_origin, normal);
				normal[x] = (float)s;

				vec_t dist;
				if (s == -1)
					dist = -b->mbBox.mins[x];
				else
					dist = b->mbBox.maxs[x];
				int planenum = FindOrCreateFloatPlane(normal, dist);

				int i;
				for (i = 0; i < b->numsides; i++)
					if (b->original_sides[i].planenum == planenum)
						break;
				if (i == b->numsides) {
					if (curTile->numbrushsides >= MAX_MAP_BRUSHSIDES)
						Sys_Error("MAX_MAP_BRUSHSIDES (%i)", curTile->numbrushsides);

					curTile->brushsides[curTile->numbrushsides].planenum = planenum;
					curTile->brushsides[curTile->numbrushsides].texinfo = curTile->brushsides[curTile->numbrushsides - 1].texinfo;
					curTile->numbrushsides++;
					db->numsides++;
					cb->numsides++;
				}
			}
	}
}
Пример #4
0
void
CL_ParseUpdate ( int bits )
{
	model_t		*model;
	qboolean	forcelink;
	entity_t	*ent;
	int		modnum, num, i;

	if (cls.signon == SIGNONS - 1)
	{	// first update is the final signon stage
		cls.signon = SIGNONS;
		CL_SignonReply ();
	}

	if (bits & U_MOREBITS)
	{
		i = MSG_ReadByte ();
		bits |= (i<<8);
	}

	if (bits & U_LONGENTITY)
		num = MSG_ReadShort ();
	else
		num = MSG_ReadByte ();

	ent = CL_EntityNum (num);

	for (i=0 ; i<16 ; i++)
		if (bits&(1<<i))
			bitcounts[i]++;

	if (ent->msgtime != cl.mtime[1])
		forcelink = true;	// no previous frame to lerp from
	else
		forcelink = false;

	ent->msgtime = cl.mtime[0];

	if (bits & U_MODEL)
	{
		modnum = MSG_ReadByte ();
		if (modnum >= MAX_MODELS)
			Host_Error ("CL_ParseModel: bad modnum");
	}
	else
		modnum = ent->baseline.modelindex;

	model = cl.model_precache[modnum];
	if (model != ent->model)
	{
		ent->model = model;
	// automatic animation (torches, etc) can be either all together
	// or randomized
		if (model)
		{
			if (model->synctype == ST_RAND)
				ent->syncbase = (float)(rand()&0x7fff) / 0x7fff;
			else
				ent->syncbase = 0.0;
		}
		else
			forcelink = true;	// hack to make null model players work
		if (num > 0 && num <= cl.maxclients)
			R_TranslatePlayerSkin (num - 1);
	}

	if (bits & U_FRAME)
		ent->frame = MSG_ReadByte ();
	else
		ent->frame = ent->baseline.frame;

	if (bits & U_COLORMAP)
		i = MSG_ReadByte();
	else
		i = ent->baseline.colormap;
	if (!i)
		ent->colormap = vid.colormap;
	else
	{
		if (i > cl.maxclients)
			Sys_Error ("i >= cl.maxclients");
		ent->colormap = cl.scores[i-1].translations;
	}

	{
		int	skin;

		if (bits & U_SKIN)
			skin = MSG_ReadByte();
		else
			skin = ent->baseline.skinnum;
		if (skin != ent->skinnum) {
			ent->skinnum = skin;
			if (num > 0 && num <= cl.maxclients)
				R_TranslatePlayerSkin (num - 1);
		}
	}

	if (bits & U_EFFECTS)
		ent->effects = MSG_ReadByte();
	else
		ent->effects = ent->baseline.effects;

// shift the known values for interpolation
	VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
	VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);

	if (bits & U_ORIGIN1)
		ent->msg_origins[0][0] = MSG_ReadCoord ();
	else
		ent->msg_origins[0][0] = ent->baseline.origin[0];
	if (bits & U_ANGLE1)
		ent->msg_angles[0][0] = MSG_ReadAngle();
	else
		ent->msg_angles[0][0] = ent->baseline.angles[0];

	if (bits & U_ORIGIN2)
		ent->msg_origins[0][1] = MSG_ReadCoord ();
	else
		ent->msg_origins[0][1] = ent->baseline.origin[1];
	if (bits & U_ANGLE2)
		ent->msg_angles[0][1] = MSG_ReadAngle();
	else
		ent->msg_angles[0][1] = ent->baseline.angles[1];

	if (bits & U_ORIGIN3)
		ent->msg_origins[0][2] = MSG_ReadCoord ();
	else
		ent->msg_origins[0][2] = ent->baseline.origin[2];
	if (bits & U_ANGLE3)
		ent->msg_angles[0][2] = MSG_ReadAngle();
	else
		ent->msg_angles[0][2] = ent->baseline.angles[2];

	if ( bits & U_NOLERP )
		ent->forcelink = true;

	if ( forcelink )
	{	// didn't have an update last message
		VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
		VectorCopy (ent->msg_origins[0], ent->origin);
		VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
		VectorCopy (ent->msg_angles[0], ent->angles);
		ent->forcelink = true;
	}
}
Пример #5
0
//Split out like this for ASM to call.
void BOPS_Error (void) {
	Sys_Error ("BoxOnPlaneSide:  Bad signbits");
}
Пример #6
0
/*
===============
R_SnowEffect

MG
===============
*/
void R_SnowEffect (vec3_t org1,vec3_t org2,int flags,vec3_t alldir,int count)
{
	int i,j,holdint;
	particle_t	*p;
	mleaf_t		*l;
	
	count *= Cvar_VariableValue("snow_active");
	for (i=0 ; i<count ; i++)
	{
		p = AllocParticle();
		if (!p)
			return;
		
		p->vel[0] = alldir[0];  //X and Y motion
		p->vel[1] = alldir[1];
		p->vel[2] = alldir[2] * ((rand() & 15) + 7)/10;
		
		p->flags = flags;

#ifdef GLQUAKE
		if(rand()&0x7f<=1)//have a console variable 'happy_snow' that makes all snowflakes happy snow!
			p->count = 69;	//happy snow!
		else if(flags & SFL_FLUFFY || (flags&SFL_MIXED && (rand()&3)))
			p->count = (rand()&31)+10;//From 10 to 41 scale, will be divided
		else
			p->count = 10;
#else
		if(flags & SFL_FLUFFY || (flags&SFL_MIXED && (rand()&3)))
			p->count = (rand()&3)+2;//From 2 to 5 extra
		else
			p->count = 1;	//Only one particle

#endif


		if(flags&SFL_HALF_BRIGHT)//Start darker
			p->color = 26 + (rand()%5);
		else
			p->color = 18 + (rand()%12);

		if(!(flags&SFL_NO_TRANS))//Start translucent
			p->color += 256;

		p->die = cl.time + 7;
		p->ramp = (rand()&3);
		//p->veer = veer;
		p->type = pt_snow;
		
		holdint=org2[0] - org1[0];
		p->org[0] = org1[0] + (rand() % holdint);
		holdint=org2[1] - org1[1];
		p->org[1] = org1[1] + (rand() % holdint);
		p->org[2] = org2[2];
		

		j=50;
		l = Mod_PointInLeaf (p->org, cl.worldmodel);
//		while(SV_PointContents(p->org)!=CONTENTS_EMPTY && j<50)
		while(l->contents!=CONTENTS_EMPTY && j)
		{//Make sure it doesn't start in a solid
			holdint=org2[0] - org1[0];
			p->org[0] = org1[0] + (rand() % holdint);
			holdint=org2[1] - org1[1];
			p->org[1] = org1[1] + (rand() % holdint);
			j--;//No infinite loops
			l = Mod_PointInLeaf (p->org, cl.worldmodel);
		}
		if(l->contents!=CONTENTS_EMPTY)
			Sys_Error ("Snow entity top plane is not in an empty area (sorry!)");

		VectorCopy(org1,p->min_org);
		VectorCopy(org2,p->max_org);
	}
}
Пример #7
0
void *dos_getmaxlockedmem(int *size)
{
	__dpmi_free_mem_info	meminfo;
	__dpmi_meminfo			info;
	int						working_size;
	void					*working_memory;
	int						last_locked;
	int						extra, 	i, j, allocsize;
	static char				*msg = "Locking data...";
	int						m, n;
	byte					*x;
 
// first lock all the current executing image so the locked count will
// be accurate.  It doesn't hurt to lock the memory multiple times
	last_locked = __djgpp_selector_limit + 1;
	info.size = last_locked - 4096;
	info.address = __djgpp_base_address + 4096;

	if (lockmem)
	{
		if(__dpmi_lock_linear_region(&info))
		{
			Sys_Error ("Lock of current memory at 0x%lx for %ldKb failed!\n",
						info.address, info.size/1024);
		}
	}

	__dpmi_get_free_memory_information(&meminfo);

	if (!win95)		/* Not windows or earlier than Win95 */
	{
		working_size = meminfo.maximum_locked_page_allocation_in_pages * 4096;
	}
	else
	{
		working_size = meminfo.largest_available_free_block_in_bytes -
				LEAVE_FOR_CACHE;
	}

	working_size &= ~0xffff;		/* Round down to 64K */
	working_memory += 0x10000;

	do
	{
		working_size -= 0x10000;		/* Decrease 64K and try again */
		working_memory = sbrk(working_size);
	} while (working_memory == (void *)-1);

	extra = 0xfffc - ((unsigned)sbrk(0) & 0xffff);

	if (extra > 0)
	{
		sbrk(extra);
		working_size += extra;
	}

// now grab the memory
	info.address = last_locked + __djgpp_base_address;

	if (!win95)
	{
	    info.size = __djgpp_selector_limit + 1 - last_locked;

		while (info.size > 0 && __dpmi_lock_linear_region(&info))
		{
			info.size -= 0x1000;
			working_size -= 0x1000;
			sbrk(-0x1000);
		}
	}
	else
	{			/* Win95 section */
		j = COM_CheckParm("-winmem");

		if (j)
		{
			allocsize = ((int)(Q_atoi(com_argv[j+1]))) * 0x100000 +
					LOCKED_FOR_MALLOC;

			if (allocsize < (MINIMUM_WIN_MEMORY + LOCKED_FOR_MALLOC))
				allocsize = MINIMUM_WIN_MEMORY + LOCKED_FOR_MALLOC;
		}
		else
		{
			allocsize = MINIMUM_WIN_MEMORY + LOCKED_FOR_MALLOC;
		}

		if (!lockmem)
		{
		// we won't lock, just sbrk the memory
			info.size = allocsize;
			goto UpdateSbrk;
		}

		// lock the memory down
		write (STDOUT, msg, strlen (msg));

		for (j=allocsize ; j>(MINIMUM_WIN_MEMORY + LOCKED_FOR_MALLOC) ;
			 j -= 0x100000)
		{
			info.size = j;
	
			if (!__dpmi_lock_linear_region(&info))
				goto Locked;
	
			write (STDOUT, ".", 1);
		}

	// finally, try with the absolute minimum amount
		for (i=0 ; i<10 ; i++)
		{
			info.size = MINIMUM_WIN_MEMORY + LOCKED_FOR_MALLOC;

			if (!__dpmi_lock_linear_region(&info))
				goto Locked;
		}

		Sys_Error ("Can't lock memory; %d Mb lockable RAM required. "
				   "Try shrinking smartdrv.", info.size / 0x100000);

Locked:

UpdateSbrk:

		info.address += info.size;
		info.address -= __djgpp_base_address + 4; // ending point, malloc align
		working_size = info.address - (int)working_memory;
		sbrk(info.address-(int)sbrk(0));		// negative adjustment
	}


	if (lockunlockmem)
	{
		__dpmi_unlock_linear_region (&info);
		printf ("Locked and unlocked %d Mb data\n", working_size / 0x100000);
	}
	else if (lockmem)
	{
		printf ("Locked %d Mb data\n", working_size / 0x100000);
	}
	else
	{
		printf ("Allocated %d Mb data\n", working_size / 0x100000);
	}

// touch all the memory to make sure it's there. The 16-page skip is to
// keep Win 95 from thinking we're trying to page ourselves in (we are
// doing that, of course, but there's no reason we shouldn't)
	x = (byte *)working_memory;

	for (n=0 ; n<4 ; n++)
	{
		for (m=0 ; m<(working_size - 16 * 0x1000) ; m += 4)
		{
			sys_checksum += *(int *)&x[m];
			sys_checksum += *(int *)&x[m + 16 * 0x1000];
		}
	}

// give some of what we locked back for malloc before returning.  Done
// by cheating and passing a negative value to sbrk
	working_size -= LOCKED_FOR_MALLOC;
	sbrk( -(LOCKED_FOR_MALLOC));
	*size = working_size;
	return working_memory;
}
Пример #8
0
/*
============
GetWavinfo
============
*/
wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
{
	wavinfo_t	info;
	int     i;
	int     format;
	int		samples;

	memset (&info, 0, sizeof(info));

	if (!wav)
		return info;
		
	iff_data = wav;
	iff_end = wav + wavlength;

// find "RIFF" chunk
	FindChunk("RIFF");
	if (!(data_p && !Q_strncmp(data_p+8, "WAVE", 4)))
	{
		Con_Printf("Missing RIFF/WAVE chunks\n");
		return info;
	}

// get "fmt " chunk
	iff_data = data_p + 12;
// DumpChunks ();

	FindChunk("fmt ");
	if (!data_p)
	{
		Con_Printf("Missing fmt chunk\n");
		return info;
	}
	data_p += 8;
	format = GetLittleShort();
	if (format != 1)
	{
		Con_Printf("Microsoft PCM format only\n");
		return info;
	}

	info.channels = GetLittleShort();
	info.rate = GetLittleLong();
	data_p += 4+2;
	info.width = GetLittleShort() / 8;

// get cue chunk
	FindChunk("cue ");
	if (data_p)
	{
		data_p += 32;
		info.loopstart = GetLittleLong();
//		Con_Printf("loopstart=%d\n", sfx->loopstart);

	// if the next chunk is a LIST chunk, look for a cue length marker
		FindNextChunk ("LIST");
		if (data_p)
		{
			if (!strncmp (data_p + 28, "mark", 4))
			{	// this is not a proper parse, but it works with cooledit...
				data_p += 24;
				i = GetLittleLong ();	// samples in loop
				info.samples = info.loopstart + i;
//				Con_Printf("looped length: %i\n", i);
			}
		}
	}
	else
		info.loopstart = -1;

// find data chunk
	FindChunk("data");
	if (!data_p)
	{
		Con_Printf("Missing data chunk\n");
		return info;
	}

	data_p += 4;
	samples = GetLittleLong () / info.width;

	if (info.samples)
	{
		if (samples < info.samples)
			Sys_Error ("Sound %s has a bad loop length", name);
	}
	else
		info.samples = samples;

	info.dataofs = data_p - wav;
	
	return info;
}
Пример #9
0
/*
================
Host_FindMaxClients
================
*/
void	Host_FindMaxClients (void)
{
	int	cmdline_dedicated;
	int cmdline_listen;

	svs.maxclients = 1;

	cmdline_dedicated = COM_CheckParm ("-dedicated");
	if (cmdline_dedicated)
	{
		cls.state = ca_dedicated;
		if (cmdline_dedicated != (com_argc - 1))
			svs.maxclients = atoi (com_argv[cmdline_dedicated+1]);
		else
			svs.maxclients = 8;		// Default for -dedicated with no command line
	}
	else
		cls.state = ca_disconnected;

	cmdline_listen = COM_CheckParm ("-listen");
	if (cmdline_listen)
	{
		if (cls.state == ca_dedicated)
			Sys_Error ("Only one of -dedicated or -listen can be specified");
		if (cmdline_listen != (com_argc - 1))
			svs.maxclients = atoi (com_argv[cmdline_listen+1]);
		else
			svs.maxclients = 8;
	}
	if (svs.maxclients < 1)
		svs.maxclients = 8;
	else if (svs.maxclients > MAX_SCOREBOARD)
		svs.maxclients = MAX_SCOREBOARD;

	if (cmdline_dedicated || cmdline_listen) {
		// Baker: only do this if -dedicated or listen
		// So, why does this need done at all since all we are doing is an allocation below.
		// Well, here is why ....
		// we really want the -dedicated and -listen parameters to operate as expected and
		// not be ignored.  This limit shouldn't be able to be changed in game if specified.
		// But we don't want to hurt our ability to play against the bots either.
	svs.maxclientslimit = svs.maxclients;
	} else {
		svs.maxclientslimit = 16; // Baker: the new default for using neither -listen or -dedicated
	}

	if (svs.maxclientslimit < 4)
		svs.maxclientslimit = 4;
	svs.clients = Hunk_AllocName (svs.maxclientslimit*sizeof(client_t), "clients");

	if (svs.maxclients > 1)
	{
#ifdef SUPPORTS_KUROK
		if (deathmatch.value > 1)
			Cvar_SetValueByRef (&deathmatch, deathmatch.value);
		else
#endif
			Cvar_SetValueByRef (&deathmatch, 1.0);
	}
	else
		Cvar_SetValueByRef (&deathmatch, 0.0);
}
Пример #10
0
void main(int argc, char *argv[])
{
	double			time, oldtime, newtime;
	quakeparms_t	parms;
	fd_set	fdset;
	extern	int		net_socket;
    struct timeval timeout;
	int j;

	memset (&parms, 0, sizeof(parms));

	COM_InitArgv (argc, argv);	
	parms.argc = com_argc;
	parms.argv = com_argv;

	parms.memsize = 16*1024*1024;

	j = COM_CheckParm("-mem");
	if (j)
		parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024);
	if ((parms.membase = malloc (parms.memsize)) == NULL)
		Sys_Error("Can't allocate %ld\n", parms.memsize);

	parms.basedir = ".";


	SV_Init (&parms);

// run one frame immediately for first heartbeat
	SV_Frame (0.1);		

//
// main loop
//
	oldtime = Sys_DoubleTime () - 0.1;
	while (1)
	{
	// select on the net socket and stdin
	// the only reason we have a timeout at all is so that if the last
	// connected client times out, the message would not otherwise
	// be printed until the next event.
		FD_ZERO(&fdset);
		if (do_stdin)
			FD_SET(0, &fdset);
		FD_SET(net_socket, &fdset);
		timeout.tv_sec = 1;
		timeout.tv_usec = 0;
		if (select (net_socket+1, &fdset, NULL, NULL, &timeout) == -1)
			continue;
		stdin_ready = FD_ISSET(0, &fdset);

	// find time passed since last cycle
		newtime = Sys_DoubleTime ();
		time = newtime - oldtime;
		oldtime = newtime;
		
		SV_Frame (time);		
		
	// extrasleep is just a way to generate a f****d up connection on purpose
		if (sys_extrasleep.value)
			usleep (sys_extrasleep.value);
	}	
}
Пример #11
0
static void Sys_Android_Init( void )
{
	struct android_app *app = sys_android_app;
	JNIEnv *env;
	jobject activity = app->activity->clazz;

	// Resolve the app's internal storage root directory.
	{
		char relativePath[PATH_MAX];
		Q_snprintfz( relativePath, sizeof( relativePath ), "%s/..", app->activity->internalDataPath );
		realpath( relativePath, sys_android_internalDataPath );
	}

	// Set working directory to external data path.
	{
		char externalDataPath[PATH_MAX];
		Q_snprintfz( externalDataPath, sizeof( externalDataPath ), "%s/%d.%d/", // The trailing slash is here to make it a directory path, not a file path
			app->activity->externalDataPath, APP_VERSION_MAJOR, APP_VERSION_MINOR );
		FS_CreateAbsolutePath( externalDataPath );
		if( chdir( externalDataPath ) )
			Sys_Error( "Failed to change working directory" );
	}

	// Initialize JNI.
	if( pthread_key_create( &sys_android_jniEnvKey, Sys_Android_JNIEnvDestructor ) )
		Sys_Error( "Failed to create JNIEnv destructor" );
	env = Sys_Android_GetJNIEnv();

	// Activity class shortcut.
	{
		jclass activityClass = (*env)->GetObjectClass( env, activity );
		sys_android_activityClass = (*env)->NewGlobalRef( env, activityClass );
		sys_android_getSystemService = (*env)->GetMethodID( env, activityClass,
			"getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;" );
		(*env)->DeleteLocalRef( env, activityClass );
	}

	// Get package name.
	{
		jmethodID getPackageName;
		jstring packageNameJS;
		const char *packageNameUTF;

		getPackageName = (*env)->GetMethodID( env, sys_android_activityClass, "getPackageName", "()Ljava/lang/String;" );
		packageNameJS = (*env)->CallObjectMethod( env, activity, getPackageName );
		packageNameUTF = (*env)->GetStringUTFChars( env, packageNameJS, NULL );
		Q_strncpyz( sys_android_packageName, packageNameUTF, sizeof( sys_android_packageName ) );
		(*env)->ReleaseStringUTFChars( env, packageNameJS, packageNameUTF );
		(*env)->DeleteLocalRef( env, packageNameJS );
	}

	// Initialize the wake lock.
	{
		jstring name;
		jobject power;
		jclass powerClass;
		jmethodID newWakeLock;
		jstring tag;
		jobject wakeLock;

		name = (*env)->NewStringUTF( env, "power" );
		power = (*env)->CallObjectMethod( env, activity, sys_android_getSystemService, name );
		(*env)->DeleteLocalRef( env, name );
		powerClass = (*env)->FindClass( env, "android/os/PowerManager" );
		newWakeLock = (*env)->GetMethodID( env, powerClass, "newWakeLock",
			"(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;" );
		(*env)->DeleteLocalRef( env, powerClass );
		tag = (*env)->NewStringUTF( env, "Qfusion" );
		wakeLock = (*env)->CallObjectMethod( env, power, newWakeLock, 1 /* PARTIAL_WAKE_LOCK */, tag );
		(*env)->DeleteLocalRef( env, tag );
		(*env)->DeleteLocalRef( env, power );
		sys_android_wakeLock = (*env)->NewGlobalRef( env, wakeLock );
		(*env)->DeleteLocalRef( env, wakeLock );
	}

	// Initialize the high-performance Wi-Fi lock.
	{
		jstring name;
		jobject wifi;
		jclass wifiClass;
		jmethodID createWifiLock;
		jstring tag;
		jobject wifiLock;

		name = (*env)->NewStringUTF( env, "wifi" );
		wifi = (*env)->CallObjectMethod( env, activity, sys_android_getSystemService, name );
		(*env)->DeleteLocalRef( env, name );
		wifiClass = (*env)->FindClass( env, "android/net/wifi/WifiManager" );
		createWifiLock = (*env)->GetMethodID( env, wifiClass, "createWifiLock",
			"(ILjava/lang/String;)Landroid/net/wifi/WifiManager$WifiLock;" );
		(*env)->DeleteLocalRef( env, wifiClass );
		tag = (*env)->NewStringUTF( env, "Qfusion" );
		wifiLock = (*env)->CallObjectMethod( env, wifi, createWifiLock, 3 /* WIFI_MODE_FULL_HIGH_PERF */, tag );
		(*env)->DeleteLocalRef( env, tag );
		(*env)->DeleteLocalRef( env, wifi );
		sys_android_wifiLock = (*env)->NewGlobalRef( env, wifiLock );
		(*env)->DeleteLocalRef( env, wifiLock );
	}

	// Set native app cmd handler to the actual one.
	app->onAppCmd = Sys_Android_OnAppCmd;

	// Check if browser links can be clicked.
	sys_android_browserAvailable = Sys_Android_CheckBrowserAvailability();
}
Пример #12
0
void NET_Init (void)
{
	int			i;
	qsocket_t	*s;

	i = COM_CheckParm ("-port");
	if (!i)
		i = COM_CheckParm ("-udpport");
	if (!i)
		i = COM_CheckParm ("-ipxport");

	if (i)
	{
		if (i < com_argc-1)
			DEFAULTnet_hostport = Q_atoi (com_argv[i+1]);
		else
			Sys_Error ("NET_Init: you must specify a number after -port");
	}
	net_hostport = DEFAULTnet_hostport;

	net_numsockets = svs.maxclientslimit;
	if (cls.state != ca_dedicated)
		net_numsockets++;
	if (COM_CheckParm("-listen") || cls.state == ca_dedicated)
		listening = true;

	SetNetTime();

	for (i = 0; i < net_numsockets; i++)
	{
		s = (qsocket_t *)Hunk_AllocName(sizeof(qsocket_t), "qsocket");
		s->next = net_freeSockets;
		net_freeSockets = s;
		s->disconnected = true;
	}

	// allocate space for network message buffer
	SZ_Alloc (&net_message, NET_MAXMESSAGE);

	Cvar_RegisterVariable (&net_messagetimeout);
	Cvar_RegisterVariable (&hostname);

	Cmd_AddCommand ("slist", NET_Slist_f);
	Cmd_AddCommand ("listen", NET_Listen_f);
	Cmd_AddCommand ("maxplayers", MaxPlayers_f);
	Cmd_AddCommand ("port", NET_Port_f);

	// initialize all the drivers
	for (i = net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++)
	{
		if (net_drivers[net_driverlevel].Init() == -1)
			continue;
		i++;
		net_drivers[net_driverlevel].initialized = true;
		if (listening)
			net_drivers[net_driverlevel].Listen (true);
	}

	/* Loop_Init() returns -1 for dedicated server case,
	 * therefore the i == 0 check is correct */
	if (i == 0
			&& cls.state == ca_dedicated
	   )
	{
		Sys_Error("Network not available!");
	}

	if (*my_ipx_address)
	{
		Con_DPrintf("IPX address %s\n", my_ipx_address);
	}
	if (*my_tcpip_address)
	{
		Con_DPrintf("TCP/IP address %s\n", my_tcpip_address);
	}
}
/*
================
R_DrawSprite
================
*/
void R_DrawSprite (void)
{
	int				i;
	msprite_t		*psprite;
	vec3_t			tvec;
	float			dot, angle, sr, cr;

	psprite = currententity->model->cache.data;

	r_spritedesc.pspriteframe = R_GetSpriteframe (psprite);

	sprite_width = r_spritedesc.pspriteframe->width;
	sprite_height = r_spritedesc.pspriteframe->height;

// TODO: make this caller-selectable
	if (psprite->type == SPR_FACING_UPRIGHT)
	{
	// generate the sprite's axes, with vup straight up in worldspace, and
	// r_spritedesc.vright perpendicular to modelorg.
	// This will not work if the view direction is very close to straight up or
	// down, because the cross product will be between two nearly parallel
	// vectors and starts to approach an undefined state, so we don't draw if
	// the two vectors are less than 1 degree apart
		tvec[0] = -modelorg[0];
		tvec[1] = -modelorg[1];
		tvec[2] = -modelorg[2];
		VectorNormalize (tvec);
		dot = tvec[2];	// same as DotProduct (tvec, r_spritedesc.vup) because
						//  r_spritedesc.vup is 0, 0, 1
		if ((dot > 0.999848) || (dot < -0.999848))	// cos(1 degree) = 0.999848
			return;
		r_spritedesc.vup[0] = 0;
		r_spritedesc.vup[1] = 0;
		r_spritedesc.vup[2] = 1;
		r_spritedesc.vright[0] = tvec[1];
								// CrossProduct(r_spritedesc.vup, -modelorg,
		r_spritedesc.vright[1] = -tvec[0];
								//              r_spritedesc.vright)
		r_spritedesc.vright[2] = 0;
		VectorNormalize (r_spritedesc.vright);
		r_spritedesc.vpn[0] = -r_spritedesc.vright[1];
		r_spritedesc.vpn[1] = r_spritedesc.vright[0];
		r_spritedesc.vpn[2] = 0;
					// CrossProduct (r_spritedesc.vright, r_spritedesc.vup,
					//  r_spritedesc.vpn)
	}
	else if (psprite->type == SPR_VP_PARALLEL)
	{
	// generate the sprite's axes, completely parallel to the viewplane. There
	// are no problem situations, because the sprite is always in the same
	// position relative to the viewer
		for (i=0 ; i<3 ; i++)
		{
			r_spritedesc.vup[i] = vup[i];
			r_spritedesc.vright[i] = vright[i];
			r_spritedesc.vpn[i] = vpn[i];
		}
	}
	else if (psprite->type == SPR_VP_PARALLEL_UPRIGHT)
	{
	// generate the sprite's axes, with vup straight up in worldspace, and
	// r_spritedesc.vright parallel to the viewplane.
	// This will not work if the view direction is very close to straight up or
	// down, because the cross product will be between two nearly parallel
	// vectors and starts to approach an undefined state, so we don't draw if
	// the two vectors are less than 1 degree apart
		dot = vpn[2];	// same as DotProduct (vpn, r_spritedesc.vup) because
						//  r_spritedesc.vup is 0, 0, 1
		if ((dot > 0.999848) || (dot < -0.999848))	// cos(1 degree) = 0.999848
			return;
		r_spritedesc.vup[0] = 0;
		r_spritedesc.vup[1] = 0;
		r_spritedesc.vup[2] = 1;
		r_spritedesc.vright[0] = vpn[1];
										// CrossProduct (r_spritedesc.vup, vpn,
		r_spritedesc.vright[1] = -vpn[0];	//  r_spritedesc.vright)
		r_spritedesc.vright[2] = 0;
		VectorNormalize (r_spritedesc.vright);
		r_spritedesc.vpn[0] = -r_spritedesc.vright[1];
		r_spritedesc.vpn[1] = r_spritedesc.vright[0];
		r_spritedesc.vpn[2] = 0;
					// CrossProduct (r_spritedesc.vright, r_spritedesc.vup,
					//  r_spritedesc.vpn)
	}
	else if (psprite->type == SPR_ORIENTED)
	{
	// generate the sprite's axes, according to the sprite's world orientation
		AngleVectors (currententity->angles, r_spritedesc.vpn, r_spritedesc.vright, r_spritedesc.vup);
	}
	else if (psprite->type == SPR_VP_PARALLEL_ORIENTED)
	{
	// generate the sprite's axes, parallel to the viewplane, but rotated in
	// that plane around the center according to the sprite entity's roll
	// angle. So vpn stays the same, but vright and vup rotate
		angle = currententity->angles[ROLL] * (M_PI*2 / 360);
		sr = sin(angle);
		cr = cos(angle);

		for (i=0 ; i<3 ; i++)
		{
			r_spritedesc.vpn[i] = vpn[i];
			r_spritedesc.vright[i] = vright[i] * cr + vup[i] * sr;
			r_spritedesc.vup[i] = vright[i] * -sr + vup[i] * cr;
		}
	}
	else
	{
		Sys_Error ("R_DrawSprite: Bad sprite type %d", psprite->type);
	}

	R_RotateSprite (psprite->beamlength);

	R_SetupAndDrawSprite ();
}
/*
================
R_SetupAndDrawSprite
================
*/
void R_SetupAndDrawSprite ()
{
	int			i, nump;
	float		dot, scale, *pv;
	vec5_t		*pverts;
	vec3_t		left, up, right, down, transformed, local;
	emitpoint_t	outverts[MAXWORKINGVERTS+1], *pout;

	dot = DotProduct (r_spritedesc.vpn, modelorg);

// backface cull
	if (dot >= 0)
		return;

// build the sprite poster in worldspace
	VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->right, right);
	VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->up, up);
	VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->left, left);
	VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->down, down);

	pverts = clip_verts[0];

	pverts[0][0] = r_entorigin[0] + up[0] + left[0];
	pverts[0][1] = r_entorigin[1] + up[1] + left[1];
	pverts[0][2] = r_entorigin[2] + up[2] + left[2];
	pverts[0][3] = 0;
	pverts[0][4] = 0;

	pverts[1][0] = r_entorigin[0] + up[0] + right[0];
	pverts[1][1] = r_entorigin[1] + up[1] + right[1];
	pverts[1][2] = r_entorigin[2] + up[2] + right[2];
	pverts[1][3] = sprite_width;
	pverts[1][4] = 0;

	pverts[2][0] = r_entorigin[0] + down[0] + right[0];
	pverts[2][1] = r_entorigin[1] + down[1] + right[1];
	pverts[2][2] = r_entorigin[2] + down[2] + right[2];
	pverts[2][3] = sprite_width;
	pverts[2][4] = sprite_height;

	pverts[3][0] = r_entorigin[0] + down[0] + left[0];
	pverts[3][1] = r_entorigin[1] + down[1] + left[1];
	pverts[3][2] = r_entorigin[2] + down[2] + left[2];
	pverts[3][3] = 0;
	pverts[3][4] = sprite_height;

// clip to the frustum in worldspace
	nump = 4;
	clip_current = 0;

	for (i=0 ; i<4 ; i++)
	{
		nump = R_ClipSpriteFace (nump, &view_clipplanes[i]);
		if (nump < 3)
			return;
		if (nump >= MAXWORKINGVERTS)
			Sys_Error("R_SetupAndDrawSprite: too many points");
	}

// transform vertices into viewspace and project
	pv = &clip_verts[clip_current][0][0];
	r_spritedesc.nearzi = -999999;

	for (i=0 ; i<nump ; i++)
	{
		VectorSubtract (pv, r_origin, local);
		TransformVector (local, transformed);

		if (transformed[2] < NEAR_CLIP)
			transformed[2] = NEAR_CLIP;

		pout = &outverts[i];
		pout->zi = 1.0 / transformed[2];
		if (pout->zi > r_spritedesc.nearzi)
			r_spritedesc.nearzi = pout->zi;

		pout->s = pv[3];
		pout->t = pv[4];

		scale = xscale * pout->zi;
		pout->u = (xcenter + scale * transformed[0]);

		scale = yscale * pout->zi;
		pout->v = (ycenter - scale * transformed[1]);

		pv += sizeof (vec5_t) / sizeof (*pv);
	}

// draw it
	r_spritedesc.nump = nump;
	r_spritedesc.pverts = outverts;
	D_DrawSprite ();
}
Пример #15
0
/*
==================
BoxOnPlaneSide

Returns 1, 2, or 1 + 2
==================
*/
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, mplane_t *p)
{
	float	dist1, dist2;
	int		sides;

#if 0	// this is done by the BOX_ON_PLANE_SIDE macro before calling this
		// function
// fast axial cases
	if (p->type < 3)
	{
		if (p->dist <= emins[p->type])
			return 1;
		if (p->dist >= emaxs[p->type])
			return 2;
		return 3;
	}
#endif
	
// general case
	switch (p->signbits)
	{
	case 0:
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
		break;
	case 1:
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
		break;
	case 2:
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
		break;
	case 3:
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
		break;
	case 4:
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
		break;
	case 5:
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
		break;
	case 6:
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
		break;
	case 7:
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
		break;
	default:
		dist1 = dist2 = 0;		// shut up compiler
		BOPS_Error ();
		break;
	}

#if 0
	int		i;
	vec3_t	corners[2];

	for (i=0 ; i<3 ; i++)
	{
		if (plane->normal[i] < 0)
		{
			corners[0][i] = emins[i];
			corners[1][i] = emaxs[i];
		}
		else
		{
			corners[1][i] = emins[i];
			corners[0][i] = emaxs[i];
		}
	}
	dist = DotProduct (plane->normal, corners[0]) - plane->dist;
	dist2 = DotProduct (plane->normal, corners[1]) - plane->dist;
	sides = 0;
	if (dist1 >= 0)
		sides = 1;
	if (dist2 < 0)
		sides |= 2;

#endif

	sides = 0;
	if (dist1 >= p->dist)
		sides = 1;
	if (dist2 < p->dist)
		sides |= 2;

#ifdef PARANOID
if (sides == 0)
	Sys_Error ("BoxOnPlaneSide: sides==0");
#endif

	return sides;
}
Пример #16
0
/*
====================
Host_Init
====================
*/
void Host_Init (quakeparms_t *parms)
{
	#if defined(_WIN32) && defined(GLQUAKE)
	FILE *fp = fopen("opengl32.dll","r");
	if (fp) {
		// exists
		fclose(fp);
		Sys_Error ("OpenGL32.dll found in Quake folder.  You must delete this file from your Quake folder to run this engine.");
	}
	#endif // Windows only

	if (standard_quake)
		minimum_memory = MINIMUM_MEMORY;
	else
		minimum_memory = MINIMUM_MEMORY_LEVELPAK;

	if (COM_CheckParm ("-minmemory"))
		parms->memsize = minimum_memory;

	host_parms = *parms;

	if (parms->memsize < minimum_memory)
		Sys_Error ("Only %4.1f megs of memory available, can't execute game and memsize = %i and minimum memory is %i", parms->memsize / (float)0x100000, parms->memsize, minimum_memory);

	com_argc = parms->argc;
	com_argv = parms->argv;
#ifdef SUPPORTS_CHEATFREE
	// JPG 3.00 - moved this here
#if defined(_WIN32)
	srand(time(NULL) ^ _getpid());
#else
	srand(time(NULL) ^ getpid());
#endif
#endif

	Memory_Init (parms->membase, parms->memsize);
	Cbuf_Init ();
	Cmd_Init ();
	Cvar_Init ();
	V_Init ();
	Chase_Init ();
	Host_InitVCR (parms);
	COM_Init (parms->basedir);
	Host_InitLocal ();

	W_LoadWadFile ("gfx.wad");
	Key_Init ();

	Con_Init ();
	M_Init ();
	PR_Init ();
	Mod_Init ();
#ifdef PROQUAKE_EXTENSION
	Security_Init ();	// JPG 3.20 - cheat free
#endif
	NET_Init ();
	SV_Init ();
#ifdef PROQUAKE_EXTENSION
	IPLog_Init ();	// JPG 1.05 - ip address logging

	Con_Printf ("Exe: "__TIME__" "__DATE__"\n");
#endif
#ifdef PSP_SYSTEM_STATS
	Con_Printf ("Insomnia ProQuake Engine v 4.71 Rev4\n"); //(EBOOT: "__TIME__" "__DATE__")\n");

	int currentCPU = scePowerGetCpuClockFrequency();
	int currentVRAM = sceGeEdramGetSize();
    int currentVRAMADD = sceGeEdramGetAddr();
	int currentRAMAVAIL = sceKernelTotalFreeMemSize();

#ifdef NORMAL_MODEL
	Con_Printf ("PSP Normal 32MB RAM Mode \n");
#endif
#ifdef SLIM_MODEL
	Con_Printf ("PSP Slim 64MB RAM Mode \n");
#endif

	Con_Printf ("%4.1f megabyte heap \n",parms->memsize/ (1024*1024.0));
	Con_Printf ("%4.1f PSP application heap \n",1.0f*PSP_HEAP_SIZE_MB);
	Con_Printf ("%d VRAM \n",currentVRAM);
    Con_Printf ("%d VRAM Address \n",currentVRAMADD);
    Con_Printf ("%d Current Total RAM \n",currentRAMAVAIL);

	Con_Printf ("CPU Speed %d MHz\n", currentCPU);
	Con_Printf ("%s \n", com_gamedir);

	
	
	R_InitTextures ();		// needed even for dedicated servers
#else
	Con_Printf ("%4.1f megabyte heap\n",parms->memsize/ (1024*1024.0));
#endif

	if (cls.state != ca_dedicated)
	{
		host_basepal = (byte *)COM_LoadHunkFile ("gfx/palette.lmp");
		if (!host_basepal)
			Sys_Error ("Couldn't load gfx/palette.lmp");
		host_colormap = (byte *)COM_LoadHunkFile ("gfx/colormap.lmp");
		if (!host_colormap)
			Sys_Error ("Couldn't load gfx/colormap.lmp");

#ifndef _WIN32 // on non win32, mouse comes before video for security reasons
		IN_Init ();
#endif
		VID_Init (host_basepal);

        Draw_Init ();
		SCR_Init ();
		R_Init ();
#ifndef	_WIN32
	// on Win32, sound initialization has to come before video initialization, so we
	// can put up a popup if the sound hardware is in use
		S_Init ();
#else

#ifdef	GLQUAKE
	// FIXME: doesn't use the new one-window approach yet
		S_Init ();
#endif

#endif	// _WIN32
		CDAudio_Init ();
		Sbar_Init ();
		CL_Init ();
#ifdef _WIN32 // on non win32, mouse comes before video for security reasons
		IN_Init ();
#endif

#ifdef _WIN32
		// Baker: 3.99m to get sys info
		// must be AFTER video init stuff
		Sys_InfoInit();  // We don't care about dedicated servers for this

		// Baker 3.76 - Autoplay demo

		if (com_argc >= 2)
		{
			char *infile = com_argv[1];

			if (infile[0] && infile[0] != '-' && infile[0] != '+') {
				char tmp[1024] = {0}, *ext = COM_FileExtension(infile);

				if (!strncasecmp(ext, "dem", sizeof("dem")))
					snprintf(tmp, sizeof(tmp), "playdemo \"%s\"\n", infile);

				if (tmp[0])
				{
					nostartdemos = true;
					Cbuf_AddText(tmp);
				}
			}
		}
#endif


	}

	Cbuf_InsertText ("exec quake.rc\n");

#ifdef PROQUAKE_EXTENSION
	// Baker 3.80x: this is a hack

	if (!isDedicated) {

		Cbuf_AddText ("\nsavefov\n");
		Cbuf_AddText ("savesensitivity\n");
	}
#endif
	Hunk_AllocName (0, "-HOST_HUNKLEVEL-");
	host_hunklevel = Hunk_LowMark ();

	host_initialized = true;

	Con_Printf ("Host Initialized\n");
	Sys_Printf ("========Quake Initialized=========\n");
}
Пример #17
0
/*
	Mod_LoadAllSkins
*/
void *
Mod_LoadAllSkins (int numskins, daliasskintype_t *pskintype, int *pskinindex)
{
	int         snum, gnum, t;
	int         skinsize;
	byte       *skin;
	int         groupskins;
	daliasskingroup_t *pinskingroup;
	daliasskininterval_t *pinskinintervals;
	maliasskindesc_t *pskindesc;
	maliasskingroup_t *paliasskingroup;
	float      *poutskinintervals;

	if (numskins < 1 || numskins > MAX_SKINS)
		Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins);

	skinsize = pheader->mdl.skinwidth * pheader->mdl.skinheight;
	pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t), loadname);

	*pskinindex = (byte *) pskindesc - (byte *) pheader;

	for (snum = 0; snum < numskins; snum++) {
		pskindesc[snum].type = pskintype->type;
		if (pskintype->type == ALIAS_SKIN_SINGLE) {
			skin = (byte *) (pskintype + 1);
			skin =
				Mod_LoadSkin (skin, skinsize, &pskindesc[snum].skin, snum, 0);
		} else {
			pskintype++;
			pinskingroup = (daliasskingroup_t *) pskintype;
			groupskins = LittleLong (pinskingroup->numskins);

			t = (int) &((maliasskingroup_t *) 0)->skindescs[groupskins];
			paliasskingroup = Hunk_AllocName (t, loadname);
			paliasskingroup->numskins = groupskins;

			pskindesc[snum].skin = (byte *) paliasskingroup - (byte *) pheader;

			pinskinintervals = (daliasskininterval_t *) (pinskingroup + 1);
			poutskinintervals = Hunk_AllocName (groupskins * sizeof (float),
												loadname);
			paliasskingroup->intervals =
				(byte *) poutskinintervals - (byte *) pheader;
			for (gnum = 0; gnum < groupskins; gnum++) {
				*poutskinintervals = LittleFloat (pinskinintervals->interval);
				if (*poutskinintervals <= 0)
					Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0");

				poutskinintervals++;
				pinskinintervals++;
			}

			pskintype = (void *) pinskinintervals;
			skin = (byte *) pskintype;

			for (gnum = 0; gnum < groupskins; gnum++) {
				paliasskingroup->skindescs[gnum].type = ALIAS_SKIN_SINGLE;
				skin =
					Mod_LoadSkin (skin, skinsize,
								  &paliasskingroup->skindescs[gnum].skin, snum,
								  gnum);
			}
		}
		pskintype = (daliasskintype_t *) skin;
	}

	return pskintype;
}
Пример #18
0
/*
==========
Skin_Cache

Returns a pointer to the skin bitmap, or NULL to use the default
==========
*/
byte	*Skin_Cache (skin_t *skin)
{
	char	name[1024];
	byte	*raw;
	byte	*out, *pix;
	pcx_t	*pcx;
	int		x, y;
	int		dataByte;
	int		runLength;

	if (cls.downloadtype == dl_skin)
		return NULL;		// use base until downloaded

	if (noskins.value==1) // JACK: So NOSKINS > 1 will show skins, but
		return NULL;	  // not download new ones.

	if (skin->failedload)
		return NULL;

	out = Cache_Check (&skin->cache);
	if (out)
		return out;

//
// load the pic from disk
//
	sprintf (name, "skins/%s.pcx", skin->name);
	raw = COM_LoadTempFile (name);
	if (!raw)
	{
		Con_Printf ("Couldn't load skin %s\n", name);
		sprintf (name, "skins/%s.pcx", baseskin.string);
		raw = COM_LoadTempFile (name);
		if (!raw)
		{
			skin->failedload = true;
			return NULL;
		}
	}

//
// 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 >= 320
		|| pcx->ymax >= 200)
	{
		skin->failedload = true;
		Con_Printf ("Bad skin %s\n", name);
		return NULL;
	}
	
	out = Cache_Alloc (&skin->cache, 320*200, skin->name);
	if (!out)
		Sys_Error ("Skin_Cache: couldn't allocate");

	pix = out;
	memset (out, 0, 320*200);

	for (y=0 ; y<pcx->ymax ; y++, pix += 320)
	{
		for (x=0 ; x<=pcx->xmax ; )
		{
			if (raw - (byte*)pcx > com_filesize) 
			{
				Cache_Free (&skin->cache);
				skin->failedload = true;
				Con_Printf ("Skin %s was malformed.  You should delete it.\n", name);
				return NULL;
			}
			dataByte = *raw++;

			if((dataByte & 0xC0) == 0xC0)
			{
				runLength = dataByte & 0x3F;
				if (raw - (byte*)pcx > com_filesize) 
				{
					Cache_Free (&skin->cache);
					skin->failedload = true;
					Con_Printf ("Skin %s was malformed.  You should delete it.\n", name);
					return NULL;
				}
				dataByte = *raw++;
			}
			else
				runLength = 1;

			// skin sanity check
			if (runLength + x > pcx->xmax + 2) {
				Cache_Free (&skin->cache);
				skin->failedload = true;
				Con_Printf ("Skin %s was malformed.  You should delete it.\n", name);
				return NULL;
			}
			while(runLength-- > 0)
				pix[x++] = dataByte;
		}

	}

	if ( raw - (byte *)pcx > com_filesize)
	{
		Cache_Free (&skin->cache);
		skin->failedload = true;
		Con_Printf ("Skin %s was malformed.  You should delete it.\n", name);
		return NULL;
	}

	skin->failedload = false;

	return out;
}
Пример #19
0
int
UDP_Init(void)
{
    int i;
    int err;
    char buff[MAXHOSTNAMELEN];
    char *colon;
    struct hostent *local;
    netadr_t addr;

    if (COM_CheckParm("-noudp"))
	return -1;

    /* determine my name & address, default to loopback */
    myAddr.ip.l = htonl(INADDR_LOOPBACK);
    myAddr.port = htons(DEFAULTnet_hostport);
    err = gethostname(buff, MAXHOSTNAMELEN);
    if (err) {
	Con_Printf("%s: WARNING: gethostname failed (%s)\n", __func__,
		   strerror(errno));
    } else {
	buff[MAXHOSTNAMELEN - 1] = 0;
	local = gethostbyname(buff);
	if (!local) {
	    Con_Printf("%s: WARNING: gethostbyname failed (%s)\n", __func__,
			hstrerror(h_errno));
	} else if (local->h_addrtype != AF_INET) {
	    Con_Printf("%s: address from gethostbyname not IPv4\n", __func__);
	} else {
	    struct in_addr *inaddr = (struct in_addr *)local->h_addr_list[0];
	    myAddr.ip.l = inaddr->s_addr;
	}
    }

    i = COM_CheckParm("-ip");
    if (i && i < com_argc - 1) {
	bindAddr.ip.l = inet_addr(com_argv[i + 1]);
	if (bindAddr.ip.l == INADDR_NONE)
	    Sys_Error("%s: %s is not a valid IP address", __func__,
		      com_argv[i + 1]);
	Con_Printf("Binding to IP Interface Address of %s\n", com_argv[i + 1]);
    } else {
	bindAddr.ip.l = INADDR_NONE;
    }

    i = COM_CheckParm("-localip");
    if (i && i < com_argc - 1) {
	localAddr.ip.l = inet_addr(com_argv[i + 1]);
	if (localAddr.ip.l == INADDR_NONE)
	    Sys_Error("%s: %s is not a valid IP address", __func__,
		      com_argv[i + 1]);
	Con_Printf("Advertising %s as the local IP in response packets\n",
		   com_argv[i + 1]);
    } else {
	localAddr.ip.l = INADDR_NONE;
    }

    net_controlsocket = UDP_OpenSocket(0);
    if (net_controlsocket == -1) {
	Con_Printf("%s: Unable to open control socket, UDP disabled\n",
		   __func__);
	return -1;
    }

    /* myAddr may resolve to 127.0.0.1, see if we can do any better */
    memset (ifname, 0, sizeof(ifname));
    if (myAddr.ip.l == htonl(INADDR_LOOPBACK)) {
	if (udp_scan_iface(net_controlsocket) == 0)
	    Con_Printf ("UDP, Local address: %s (%s)\n",
			NET_AdrToString(&myAddr), ifname);
    }
    if (ifname[0] == 0) {
	Con_Printf ("UDP, Local address: %s\n", NET_AdrToString(&myAddr));
    }

    broadcastaddr.ip.l = INADDR_BROADCAST;
    broadcastaddr.port = htons(net_hostport);

    UDP_GetSocketAddr(net_controlsocket, &addr);
    strcpy(my_tcpip_address, NET_AdrToString(&addr));
    colon = strrchr(my_tcpip_address, ':');
    if (colon)
	*colon = 0;

    Con_Printf("UDP Initialized (%s)\n", my_tcpip_address);
    tcpipAvailable = true;

    return net_controlsocket;
}
Пример #20
0
/*
=============
GLSLGamma_GammaCorrect
=============
*/
void GLSLGamma_GammaCorrect (void)
{
	float smax, tmax;

	if (!gl_glsl_gamma_able)
		return;

	if (vid_gamma.value == 1 && vid_contrast.value == 1)
		return;

// create render-to-texture texture if needed
	if (!r_gamma_texture)
	{
		glGenTextures (1, &r_gamma_texture);
		glBindTexture (GL_TEXTURE_2D, r_gamma_texture);

		r_gamma_texture_width = glwidth;
		r_gamma_texture_height = glheight;

		if (!gl_texture_NPOT)
		{
			r_gamma_texture_width = TexMgr_Pad(r_gamma_texture_width);
			r_gamma_texture_height = TexMgr_Pad(r_gamma_texture_height);
		}
	
		glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, r_gamma_texture_width, r_gamma_texture_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	}

// create shader if needed
	if (!r_gamma_program)
	{
		GLSLGamma_CreateShaders ();
		if (!r_gamma_program)
		{
			Sys_Error("GLSLGamma_CreateShaders failed");
		}
	}
	
// copy the framebuffer to the texture
	GL_DisableMultitexture();
	glBindTexture (GL_TEXTURE_2D, r_gamma_texture);
	glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, glx, gly, glwidth, glheight);

// draw the texture back to the framebuffer with a fragment shader
	GL_UseProgramFunc (r_gamma_program);
	GL_Uniform1fFunc (gammaLoc, vid_gamma.value);
	GL_Uniform1fFunc (contrastLoc, q_min(2.0, q_max(1.0, vid_contrast.value)));
	GL_Uniform1iFunc (textureLoc, 0); // use texture unit 0

	glDisable (GL_ALPHA_TEST);
	glDisable (GL_DEPTH_TEST);

	glViewport (glx, gly, glwidth, glheight);

	smax = glwidth/(float)r_gamma_texture_width;
	tmax = glheight/(float)r_gamma_texture_height;

	glBegin (GL_QUADS);
	glTexCoord2f (0, 0);
	glVertex2f (-1, -1);
	glTexCoord2f (smax, 0);
	glVertex2f (1, -1);
	glTexCoord2f (smax, tmax);
	glVertex2f (1, 1);
	glTexCoord2f (0, tmax);
	glVertex2f (-1, 1);
	glEnd ();
	
	GL_UseProgramFunc (0);
	
// clear cached binding
	GL_ClearBindings ();
}
Пример #21
0
/*
====================
CL_GetMessage

Handles recording and playback of demos, on top of NET_ code
====================
*/
int CL_GetMessage (void)
{
	int		r, i;
	float	f;
	
	if	(cls.demoplayback)
	{
	// decide if it is time to grab the next message		
		if (cls.signon == SIGNONS)	// allways grab until fully connected
		{
			if (cls.timedemo)
			{
				if (host_framecount == cls.td_lastframe)
					return 0;		// allready read this frame's message
				cls.td_lastframe = host_framecount;
			// if this is the second frame, grab the real td_starttime
			// so the bogus time on the first frame doesn't count
				if (host_framecount == cls.td_startframe + 1)
					cls.td_starttime = realtime;
			}
			else if ( /* cl.time > 0 && */ cl.time <= cl.mtime[0])
			{
					return 0;		// don't need another message yet
			}
		}
		
	// get the next message
		fread (&net_message.cursize, 4, 1, cls.demofile);
		VectorCopy (cl.mviewangles[0], cl.mviewangles[1]);
		for (i=0 ; i<3 ; i++)
		{
			r = fread (&f, 4, 1, cls.demofile);
			cl.mviewangles[0][i] = LittleFloat (f);
		}
		
		net_message.cursize = LittleLong (net_message.cursize);
		if (net_message.cursize > MAX_MSGLEN)
			Sys_Error ("Demo message > MAX_MSGLEN");
		r = fread (net_message.data, net_message.cursize, 1, cls.demofile);
		if (r != 1)
		{
			CL_StopPlayback ();
			return 0;
		}
	
		return 1;
	}

	while (1)
	{
		r = NET_GetMessage (cls.netcon);
		
		if (r != 1 && r != 2)
			return r;
	
	// discard nop keepalive message
		if (net_message.cursize == 1 && net_message.data[0] == svc_nop)
			Con_Printf ("<-- server to client keepalive\n");
		else
			break;
	}

	if (cls.demorecording)
		CL_WriteDemoMessage ();
	
	return r;
}
Пример #22
0
/*
================
R_RenderView
================
*/
void R_RenderView (void)
{
	double	time1, time2;

	if (r_norefresh.value)
		return;

	if (!cl.worldmodel)
		Sys_Error ("R_RenderView: NULL worldmodel");

	time1 = 0; /* avoid compiler warning */
	if (r_speeds.value)
	{
		glFinish ();
		time1 = Sys_DoubleTime ();

		//johnfitz -- rendering statistics
		rs_brushpolys = rs_aliaspolys = rs_skypolys = rs_particles = rs_fogpolys = rs_megatexels =
		rs_dynamiclightmaps = rs_aliaspasses = rs_skypasses = rs_brushpasses = 0;
	}
	else if (gl_finish.value)
		glFinish ();

	R_SetupView (); //johnfitz -- this does everything that should be done once per frame

	//johnfitz -- stereo rendering -- full of hacky goodness
	if (r_stereo.value)
	{
		float eyesep = CLAMP(-8.0f, r_stereo.value, 8.0f);
		float fdepth = CLAMP(32.0f, r_stereodepth.value, 1024.0f);

		AngleVectors (r_refdef.viewangles, vpn, vright, vup);

		//render left eye (red)
		glColorMask(1, 0, 0, 1);
		VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg);
		frustum_skew = 0.5 * eyesep * NEARCLIP / fdepth;
		srand((int) (cl.time * 1000)); //sync random stuff between eyes

		R_RenderScene ();

		//render right eye (cyan)
		glClear (GL_DEPTH_BUFFER_BIT);
		glColorMask(0, 1, 1, 1);
		VectorMA (r_refdef.vieworg, 1.0f * eyesep, vright, r_refdef.vieworg);
		frustum_skew = -frustum_skew;
		srand((int) (cl.time * 1000)); //sync random stuff between eyes

		R_RenderScene ();

		//restore
		glColorMask(1, 1, 1, 1);
		VectorMA (r_refdef.vieworg, -0.5f * eyesep, vright, r_refdef.vieworg);
		frustum_skew = 0.0f;
	}
	else
	{
		R_RenderScene ();
	}
	//johnfitz

	//johnfitz -- modified r_speeds output
	time2 = Sys_DoubleTime ();
	if (r_pos.value)
		Con_Printf ("x %i y %i z %i (pitch %i yaw %i roll %i)\n",
			(int)cl_entities[cl.viewentity].origin[0],
			(int)cl_entities[cl.viewentity].origin[1],
			(int)cl_entities[cl.viewentity].origin[2],
			(int)cl.viewangles[PITCH],
			(int)cl.viewangles[YAW],
			(int)cl.viewangles[ROLL]);
	else if (r_speeds.value == 2)
		Con_Printf ("%3i ms  %4i/%4i wpoly %4i/%4i epoly %3i lmap %4i/%4i sky %1.1f mtex\n",
					(int)((time2-time1)*1000),
					rs_brushpolys,
					rs_brushpasses,
					rs_aliaspolys,
					rs_aliaspasses,
					rs_dynamiclightmaps,
					rs_skypolys,
					rs_skypasses,
					TexMgr_FrameUsage ());
	else if (r_speeds.value)
		Con_Printf ("%3i ms  %4i wpoly %4i epoly %3i lmap\n",
					(int)((time2-time1)*1000),
					rs_brushpolys,
					rs_aliaspolys,
					rs_dynamiclightmaps);
	//johnfitz
}
Пример #23
0
static void BuildTree (const float *freq)
{
	float	min1, min2;
	int	i, j, minat1, minat2;
	huffnode_t	*work[256];
	huffnode_t	*tmp;

	HuffMemBase = malloc(512 * sizeof(huffnode_t));
	if (!HuffMemBase)
		Sys_Error("Failed allocating memory for HuffTree");
	memset(HuffMemBase, 0, 512 * sizeof(huffnode_t));
	tmp = (huffnode_t *) HuffMemBase;

	for (i = 0; i < 256; tmp++, i++)
	{
		tmp->val = (unsigned char)i;
		tmp->freq = freq[i];
		tmp->zero = NULL;
		tmp->one = NULL;
		HuffLookup[i].len = 0;
		work[i] = tmp;
	}

	for (i = 0; i < 255; tmp++, i++)
	{
		minat1 = -1;
		minat2 = -1;
		min1 = 1E30;
		min2 = 1E30;

		for (j = 0; j < 256; j++)
		{
			if (!work[j])
				continue;
			if (work[j]->freq < min1)
			{
				minat2 = minat1;
				min2 = min1;
				minat1 = j;
				min1 = work[j]->freq;
			}
			else if (work[j]->freq < min2)
			{
				minat2 = j;
				min2 = work[j]->freq;
			}
		}
		if (minat1 < 0)
			Sys_Error("minat1: %d", minat1);
		if (minat2 < 0)
			Sys_Error("minat2: %d", minat2);
		tmp->zero = work[minat2];
		tmp->one = work[minat1];
		tmp->freq = work[minat2]->freq + work[minat1]->freq;
		tmp->val = 0xff;
		work[minat1] = tmp;
		work[minat2] = NULL;
	}

	HuffTree = --tmp; // last incrementation in the loop above wasn't used
	FindTab (HuffTree, 0, 0);

#if _DEBUG_HUFFMAN
	for (i = 0; i < 256; i++)
	{
		if (!HuffLookup[i].len && HuffLookup[i].len <= 32)
		{
		//	HuffPrintf("%d %d %2X\n", HuffLookup[i].len, HuffLookup[i].bits, i);
			Sys_Error("bad frequency table");
		}
	}
#endif	/* _DEBUG_HUFFMAN */
}
Пример #24
0
/**
 * @brief Draw a model using UI model definition
 */
static void UI_DrawModelNodeWithUIModel (uiNode_t *node, const char *source, modelInfo_t *mi, uiModel_t *model)
{
	qboolean autoScaleComputed = qfalse;
	vec3_t autoScale;
	vec3_t autoCenter;

	while (model) {
		/* no animation */
		mi->frame = 0;
		mi->oldframe = 0;
		mi->backlerp = 0;

		assert(model->model);
		mi->model = R_FindModel(model->model);
		if (!mi->model) {
			model = model->next;
			continue;
		}

		mi->skin = model->skin;
		mi->name = model->model;

		/* set mi pointers to model */
		mi->origin = model->origin;
		mi->angles = model->angles;
		mi->center = model->center;
		mi->color = model->color;
		mi->scale = model->scale;

		if (model->tag && model->parent) {
			/* tag and parent defined */
			uiModel_t *parentModel;
			modelInfo_t pmi;
			vec3_t pmiorigin;
			animState_t *as;
			/* place this model part on an already existing model tag */
			parentModel = UI_GetUIModel(model->parent);
			if (!parentModel) {
				Com_Printf("UI Model: Could not get the model '%s'\n", model->parent);
				break;
			}
			pmi.model = R_FindModel(parentModel->model);
			if (!pmi.model) {
				Com_Printf("UI Model: Could not get the model '%s'\n", parentModel->model);
				break;
			}

			pmi.name = parentModel->model;

			pmi.origin = pmiorigin;
			pmi.angles = parentModel->angles;
			pmi.scale = parentModel->scale;
			pmi.center = parentModel->center;
			pmi.color = parentModel->color;

			pmi.origin[0] = parentModel->origin[0] + mi->origin[0];
			pmi.origin[1] = parentModel->origin[1] + mi->origin[1];
			pmi.origin[2] = parentModel->origin[2];
			/* don't count window offset twice for tagged models */
			mi->origin[0] -= node->root->pos[0];
			mi->origin[1] -= node->root->pos[1];

			/* autoscale? */
			if (EXTRADATA(node).autoscale) {
				if (!autoScaleComputed)
					Sys_Error("Wrong order of model nodes - the tag and parent model node must be after the base model node");
				pmi.scale = autoScale;
				pmi.center = autoCenter;
			}

			as = &parentModel->animState;
			if (!as)
				Com_Error(ERR_DROP, "Model %s should have animState_t for animation %s - but doesn't\n", pmi.name, parentModel->anim);
			pmi.frame = as->frame;
			pmi.oldframe = as->oldframe;
			pmi.backlerp = as->backlerp;

			R_DrawModelDirect(mi, &pmi, model->tag);
		} else {
			/* no tag and no parent means - base model or single model */
			const char *ref;
			UI_InitModelInfoView(node, mi, model);
			Vector4Copy(node->color, mi->color);

			/* compute the scale and center for the first model.
			 * it think its the bigger of composite models.
			 * All next elements use the same result
			 */
			if (EXTRADATA(node).autoscale) {
				if (!autoScaleComputed) {
					vec2_t size;
					size[0] = node->size[0] - node->padding;
					size[1] = node->size[1] - node->padding;
					R_ModelAutoScale(size, mi, autoScale, autoCenter);
					autoScaleComputed = qtrue;
				} else {
					mi->scale = autoScale;
					mi->center = autoCenter;
				}
			}

			/* get the animation given by node properties */
			if (EXTRADATA(node).animation && *EXTRADATA(node).animation) {
				ref = UI_GetReferenceString(node, EXTRADATA(node).animation);
			/* otherwise use the standard animation from UI model definition */
			} else
				ref = model->anim;

			/* only base models have animations */
			if (ref && *ref) {
				animState_t *as = &model->animState;
				const char *anim = R_AnimGetName(as, mi->model);
				/* initial animation or animation change */
				if (anim == NULL || !Q_streq(anim, ref))
					R_AnimChange(as, mi->model, ref);
				else
					R_AnimRun(as, mi->model, cls.frametime * 1000);

				mi->frame = as->frame;
				mi->oldframe = as->oldframe;
				mi->backlerp = as->backlerp;
			}
			R_DrawModelDirect(mi, NULL, NULL);
		}

		/* next */
		model = model->next;
	}
}
Пример #25
0
/*
===============
Host_Loadgame_f
===============
*/
void Host_Loadgame_f (void)
{
	char	name[MAX_OSPATH];
	FILE	*f;
	char	mapname[MAX_QPATH];
	float	time, tfloat;
	char	str[32768];
	const char  *start;
	int	i, r;
	edict_t	*ent;
	int	entnum;
	int	version;
	float	spawn_parms[NUM_SPAWN_PARMS];

	if (cmd_source != src_command)
		return;

	if (Cmd_Argc() != 2)
	{
		Con_Printf ("load <savename> : load a game\n");
		return;
	}

	cls.demonum = -1;		// stop demo loop in case this fails

	q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1));
	COM_DefaultExtension (name, ".sav", sizeof(name));

// we can't call SCR_BeginLoadingPlaque, because too much stack space has
// been used.  The menu calls it before stuffing loadgame command
//	SCR_BeginLoadingPlaque ();

	Con_Printf ("Loading game from %s...\n", name);
	f = fopen (name, "r");
	if (!f)
	{
		Con_Printf ("ERROR: couldn't open.\n");
		return;
	}

	fscanf (f, "%i\n", &version);
	if (version != SAVEGAME_VERSION)
	{
		fclose (f);
		Con_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION);
		return;
	}
	fscanf (f, "%s\n", str);
	for (i = 0; i < NUM_SPAWN_PARMS; i++)
		fscanf (f, "%f\n", &spawn_parms[i]);
// this silliness is so we can load 1.06 save files, which have float skill values
	fscanf (f, "%f\n", &tfloat);
	current_skill = (int)(tfloat + 0.1);
	Cvar_SetValue ("skill", (float)current_skill);

	fscanf (f, "%s\n",mapname);
	fscanf (f, "%f\n",&time);

	CL_Disconnect_f ();

	SV_SpawnServer (mapname);

	if (!sv.active)
	{
		fclose (f);
		Con_Printf ("Couldn't load map\n");
		return;
	}
	sv.paused = true;		// pause until all clients connect
	sv.loadgame = true;

// load the light styles

	for (i = 0; i < MAX_LIGHTSTYLES; i++)
	{
		fscanf (f, "%s\n", str);
		sv.lightstyles[i] = (const char *)Hunk_Strdup (str, "lightstyles");
	}

// load the edicts out of the savegame file
	entnum = -1;		// -1 is the globals
	while (!feof(f))
	{
		for (i = 0; i < (int) sizeof(str) - 1; i++)
		{
			r = fgetc (f);
			if (r == EOF || !r)
				break;
			str[i] = r;
			if (r == '}')
			{
				i++;
				break;
			}
		}
		if (i == (int) sizeof(str) - 1)
		{
			fclose (f);
			Sys_Error ("Loadgame buffer overflow");
		}
		str[i] = 0;
		start = str;
		start = COM_Parse(str);
		if (!com_token[0])
			break;		// end of file
		if (strcmp(com_token,"{"))
		{
			fclose (f);
			Sys_Error ("First token isn't a brace");
		}

		if (entnum == -1)
		{	// parse the global vars
			ED_ParseGlobals (start);
		}
		else
		{	// parse an edict

			ent = EDICT_NUM(entnum);
			memset (&ent->v, 0, progs->entityfields * 4);
			ent->free = false;
			ED_ParseEdict (start, ent);

		// link it into the bsp tree
			if (!ent->free)
				SV_LinkEdict (ent, false);
		}

		entnum++;
	}

	sv.num_edicts = entnum;
	sv.time = time;

	fclose (f);

	for (i = 0; i < NUM_SPAWN_PARMS; i++)
		svs.clients->spawn_parms[i] = spawn_parms[i];

	if (cls.state != ca_dedicated)
	{
		CL_EstablishConnection ("local");
		Host_Reconnect_f ();
	}
}
Пример #26
0
int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
{
	int			bumpcount, numbumps;
	vec3_t		dir;
	float		d;
	int			numplanes;
	vec3_t		planes[MAX_CLIP_PLANES];
	vec3_t		primal_velocity, original_velocity, new_velocity;
	int			i, j;
	trace_t		trace;
	vec3_t		end;
	float		time_left;
	int			blocked;

	numbumps = 4;

	blocked = 0;
	VectorCopy (ent->v.velocity, original_velocity);
	VectorCopy (ent->v.velocity, primal_velocity);
	numplanes = 0;

	time_left = time;

	for (bumpcount=0 ; bumpcount<numbumps ; bumpcount++)
	{
		if (!ent->v.velocity[0] && !ent->v.velocity[1] && !ent->v.velocity[2])
			break;

		for (i=0 ; i<3 ; i++)
			end[i] = ent->v.origin[i] + time_left * ent->v.velocity[i];

		trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent);

		if (trace.allsolid)
		{	// entity is trapped in another solid
			VectorCopy (vec3_origin, ent->v.velocity);
			return 3;
		}

		if (trace.fraction > 0)
		{	// actually covered some distance
			VectorCopy (trace.endpos, ent->v.origin);
			VectorCopy (ent->v.velocity, original_velocity);
			numplanes = 0;
		}

		if (trace.fraction == 1)
			 break;		// moved the entire distance

		if (!trace.ent)
			Sys_Error ("SV_FlyMove: !trace.ent");

		if (trace.plane.normal[2] > 0.7)
		{
			blocked |= 1;		// floor
			if (trace.ent->v.solid == SOLID_BSP)
			{
				ent->v.flags =	(int)ent->v.flags | FL_ONGROUND;
				ent->v.groundentity = EDICT_TO_PROG(trace.ent);
			}
		}
		if (!trace.plane.normal[2])
		{
			blocked |= 2;		// step
			if (steptrace)
				*steptrace = trace;	// save for player extrafriction
		}

//
// run the impact function
//
		SV_Impact (ent, trace.ent);
		if (ent->free)
			break;		// removed by the impact function


		time_left -= time_left * trace.fraction;

	// cliped to another plane
		if (numplanes >= MAX_CLIP_PLANES)
		{	// this shouldn't really happen
			VectorCopy (vec3_origin, ent->v.velocity);
			return 3;
		}

		VectorCopy (trace.plane.normal, planes[numplanes]);
		numplanes++;

//
// modify original_velocity so it parallels all of the clip planes
//
		for (i=0 ; i<numplanes ; i++)
		{
			ClipVelocity (original_velocity, planes[i], new_velocity, 1);
			for (j=0 ; j<numplanes ; j++)
				if (j != i)
				{
					if (DotProduct (new_velocity, planes[j]) < 0)
						break;	// not ok
				}
			if (j == numplanes)
				break;
		}

		if (i != numplanes)
		{	// go along this plane
			VectorCopy (new_velocity, ent->v.velocity);
		}
		else
		{	// go along the crease
			if (numplanes != 2)
			{
//				Con_Printf ("clip velocity, numplanes == %i\n",numplanes);
				VectorCopy (vec3_origin, ent->v.velocity);
				return 7;
			}
			CrossProduct (planes[0], planes[1], dir);
			d = DotProduct (dir, ent->v.velocity);
			VectorScale (dir, d, ent->v.velocity);
		}

//
// if original velocity is against the original velocity, stop dead
// to avoid tiny occilations in sloping corners
//
		if (DotProduct (ent->v.velocity, primal_velocity) <= 0)
		{
			VectorCopy (vec3_origin, ent->v.velocity);
			return blocked;
		}
	}

	return blocked;
}
Пример #27
0
void Sys_Init( void ) {

	CoInitialize( NULL );

	// make sure the timer is high precision, otherwise
	// NT gets 18ms resolution
	timeBeginPeriod( 1 );

	// get WM_TIMER messages pumped every millisecond
//	SetTimer( NULL, 0, 100, NULL );

	cmdSystem->AddCommand( "in_restart", Sys_In_Restart_f, CMD_FL_SYSTEM, "restarts the input system" );
#ifdef DEBUG
	cmdSystem->AddCommand( "createResourceIDs", CreateResourceIDs_f, CMD_FL_TOOL, "assigns resource IDs in _resouce.h files" );
#endif
#if 0
	cmdSystem->AddCommand( "setAsyncSound", Sys_SetAsyncSound_f, CMD_FL_SYSTEM, "set the async sound option" );
#endif

	//
	// Windows user name
	//
	win32.win_username.SetString( Sys_GetCurrentUser() );

	//
	// Windows version
	//
	win32.osversion.dwOSVersionInfoSize = sizeof( win32.osversion );

	if ( !GetVersionEx( (LPOSVERSIONINFO)&win32.osversion ) )
		Sys_Error( "Couldn't get OS info" );

	if ( win32.osversion.dwMajorVersion < 4 ) {
		Sys_Error( GAME_NAME " requires Windows version 4 (NT) or greater" );
	}
	if ( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32s ) {
		Sys_Error( GAME_NAME " doesn't run on Win32s" );
	}

	if( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ) {
		if( win32.osversion.dwMajorVersion <= 4 ) {
			win32.sys_arch.SetString( "WinNT (NT)" );
		} else if( win32.osversion.dwMajorVersion == 5 && win32.osversion.dwMinorVersion == 0 ) {
			win32.sys_arch.SetString( "Win2K (NT)" );
		} else if( win32.osversion.dwMajorVersion == 5 && win32.osversion.dwMinorVersion == 1 ) {
			win32.sys_arch.SetString( "WinXP (NT)" );
		} else if ( win32.osversion.dwMajorVersion == 6 ) {
			win32.sys_arch.SetString( "Vista" );
		} else {
			win32.sys_arch.SetString( "Unknown NT variant" );
		}
	} else if( win32.osversion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) {
		if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 0 ) {
			// Win95
			if( win32.osversion.szCSDVersion[1] == 'C' ) {
				win32.sys_arch.SetString( "Win95 OSR2 (95)" );
			} else {
				win32.sys_arch.SetString( "Win95 (95)" );
			}
		} else if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 10 ) {
			// Win98
			if( win32.osversion.szCSDVersion[1] == 'A' ) {
				win32.sys_arch.SetString( "Win98SE (95)" );
			} else {
				win32.sys_arch.SetString( "Win98 (95)" );
			}
		} else if( win32.osversion.dwMajorVersion == 4 && win32.osversion.dwMinorVersion == 90 ) {
			// WinMe
		  	win32.sys_arch.SetString( "WinMe (95)" );
		} else {
		  	win32.sys_arch.SetString( "Unknown 95 variant" );
		}
	} else {
		win32.sys_arch.SetString( "unknown Windows variant" );
	}

	//
	// CPU type
	//
	if ( !idStr::Icmp( win32.sys_cpustring.GetString(), "detect" ) ) {
		idStr string;

		common->Printf( "%1.0f MHz ", Sys_ClockTicksPerSecond() / 1000000.0f );

		win32.cpuid = Sys_GetCPUId();

		string.Clear();

		if ( win32.cpuid & CPUID_AMD ) {
			string += "AMD CPU";
		} else if ( win32.cpuid & CPUID_INTEL ) {
			string += "Intel CPU";
		} else if ( win32.cpuid & CPUID_UNSUPPORTED ) {
			string += "unsupported CPU";
		} else {
			string += "generic CPU";
		}

		string += " with ";
		if ( win32.cpuid & CPUID_MMX ) {
			string += "MMX & ";
		}
		if ( win32.cpuid & CPUID_3DNOW ) {
			string += "3DNow! & ";
		}
		if ( win32.cpuid & CPUID_SSE ) {
			string += "SSE & ";
		}
		if ( win32.cpuid & CPUID_SSE2 ) {
            string += "SSE2 & ";
		}
		if ( win32.cpuid & CPUID_SSE3 ) {
			string += "SSE3 & ";
		}
		if ( win32.cpuid & CPUID_HTT ) {
			string += "HTT & ";
		}
		string.StripTrailing( " & " );
		string.StripTrailing( " with " );
		win32.sys_cpustring.SetString( string );
	} else {
		common->Printf( "forcing CPU type to " );
		idLexer src( win32.sys_cpustring.GetString(), idStr::Length( win32.sys_cpustring.GetString() ), "sys_cpustring" );
		idToken token;

		int id = CPUID_NONE;
		while( src.ReadToken( &token ) ) {
			if ( token.Icmp( "generic" ) == 0 ) {
				id |= CPUID_GENERIC;
			} else if ( token.Icmp( "intel" ) == 0 ) {
				id |= CPUID_INTEL;
			} else if ( token.Icmp( "amd" ) == 0 ) {
				id |= CPUID_AMD;
			} else if ( token.Icmp( "mmx" ) == 0 ) {
				id |= CPUID_MMX;
			} else if ( token.Icmp( "3dnow" ) == 0 ) {
				id |= CPUID_3DNOW;
			} else if ( token.Icmp( "sse" ) == 0 ) {
				id |= CPUID_SSE;
			} else if ( token.Icmp( "sse2" ) == 0 ) {
				id |= CPUID_SSE2;
			} else if ( token.Icmp( "sse3" ) == 0 ) {
				id |= CPUID_SSE3;
			} else if ( token.Icmp( "htt" ) == 0 ) {
				id |= CPUID_HTT;
			}
		}
		if ( id == CPUID_NONE ) {
			common->Printf( "WARNING: unknown sys_cpustring '%s'\n", win32.sys_cpustring.GetString() );
			id = CPUID_GENERIC;
		}
		win32.cpuid = (cpuid_t) id;
	}

	common->Printf( "%s\n", win32.sys_cpustring.GetString() );
	common->Printf( "%d MB System Memory\n", Sys_GetSystemRam() );
	common->Printf( "%d MB Video Memory\n", Sys_GetVideoRam() );
}
Пример #28
0
/*
================
SV_Physics_Client

Player character actions
================
*/
void SV_Physics_Client (edict_t	*ent, int num)
{
	if ( ! svs.clients[num-1].active )
		return;		// unconnected slot

//
// call standard client pre-think
//
	pr_global_struct->time = sv.time;
	pr_global_struct->self = EDICT_TO_PROG(ent);
	PR_ExecuteProgram (pr_global_struct->PlayerPreThink);

//
// do a move
//
	SV_CheckVelocity (ent);

//
// decide which move function to call
//
	switch ((int)ent->v.movetype)
	{
	case MOVETYPE_NONE:
		if (!SV_RunThink (ent))
			return;
		break;

	case MOVETYPE_WALK:
		if (!SV_RunThink (ent))
			return;
		if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) )
			SV_AddGravity (ent);
		SV_CheckStuck (ent);
		SV_WalkMove (ent);
		break;

	case MOVETYPE_TOSS:
	case MOVETYPE_BOUNCE:
		SV_Physics_Toss (ent);
		break;

	case MOVETYPE_FLY:
		if (!SV_RunThink (ent))
			return;
		SV_FlyMove (ent, host_frametime, NULL);
		break;

	case MOVETYPE_NOCLIP:
		if (!SV_RunThink (ent))
			return;
		VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin);
		break;

	default:
		Sys_Error ("SV_Physics_client: bad movetype %i", (int)ent->v.movetype);
	}

//
// call standard player post-think
//
	SV_LinkEdict (ent, true);

	pr_global_struct->time = sv.time;
	pr_global_struct->self = EDICT_TO_PROG(ent);
	PR_ExecuteProgram (pr_global_struct->PlayerPostThink);
}
Пример #29
0
void CL_ParseTEnt(void)
{
	int type;
	vec3_t pos;
	dlight_t *dl;
	int rnd;

	type = MSG_ReadByte(net_message);
	switch(type)
	{
	case TE_WIZSPIKE:			// spike hitting wall
		pos[0] = MSG_ReadCoord (net_message);
		pos[1] = MSG_ReadCoord (net_message);
		pos[2] = MSG_ReadCoord (net_message);
		R_RunParticleEffect (pos, vec3_origin, 20, 30);
//		S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
		break;
		
	case TE_KNIGHTSPIKE:			// spike hitting wall
		pos[0] = MSG_ReadCoord (net_message);
		pos[1] = MSG_ReadCoord (net_message);
		pos[2] = MSG_ReadCoord (net_message);
		R_RunParticleEffect (pos, vec3_origin, 226, 20);
//		S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
		break;
		
	case TE_SPIKE:			// spike hitting wall
		pos[0] = MSG_ReadCoord (net_message);
		pos[1] = MSG_ReadCoord (net_message);
		pos[2] = MSG_ReadCoord (net_message);

		R_RunParticleEffect (pos, vec3_origin, 0, 10);

		if ( rand() % 5 )
			S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
		else
		{
			rnd = rand() & 3;
			if (rnd == 1)
				S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
			else if (rnd == 2)
				S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
			else
				S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
		}
		break;
	case TE_SUPERSPIKE:			// super spike hitting wall
		pos[0] = MSG_ReadCoord (net_message);
		pos[1] = MSG_ReadCoord (net_message);
		pos[2] = MSG_ReadCoord (net_message);
		R_RunParticleEffect (pos, vec3_origin, 0, 20);

		if ( rand() % 5 )
			S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
		else
		{
			rnd = rand() & 3;
			if (rnd == 1)
				S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
			else if (rnd == 2)
				S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
			else
				S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
		}
		break;
		
	case TE_GUNSHOT:			// bullet hitting wall
		pos[0] = MSG_ReadCoord (net_message);
		pos[1] = MSG_ReadCoord (net_message);
		pos[2] = MSG_ReadCoord (net_message);
		R_RunParticleEffect (pos, vec3_origin, 0, 20);
		break;
		
	case TE_EXPLOSION:			// rocket explosion
		pos[0] = MSG_ReadCoord (net_message);
		pos[1] = MSG_ReadCoord (net_message);
		pos[2] = MSG_ReadCoord (net_message);
		R_ParticleExplosion (pos);
		break;
		dl = CL_AllocDlight (0);
		VectorCopy (pos, dl->origin);
		dl->radius = 350;
		dl->die = cl.time + 0.5;
		dl->decay = 300;
		S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
		break;
/*	//jfm:not used
	case TE_TAREXPLOSION:			// tarbaby explosion
		pos[0] = MSG_ReadCoord ();
		pos[1] = MSG_ReadCoord ();
		pos[2] = MSG_ReadCoord ();
		R_BlobExplosion (pos);

		S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
		break;
*/
	case TE_LIGHTNING1:
	case TE_LIGHTNING2:
	case TE_LIGHTNING3:
		MSG_ReadShort(net_message);
		MSG_ReadCoord(net_message);
		MSG_ReadCoord(net_message);
		MSG_ReadCoord(net_message);
		MSG_ReadCoord(net_message);
		MSG_ReadCoord(net_message);
		MSG_ReadCoord(net_message);
		break;

	case TE_STREAM_CHAIN:
	case TE_STREAM_SUNSTAFF1:
	case TE_STREAM_SUNSTAFF2:
	case TE_STREAM_LIGHTNING:
	case TE_STREAM_LIGHTNING_SMALL:
	case TE_STREAM_COLORBEAM:
	case TE_STREAM_ICECHUNKS:
	case TE_STREAM_GAZE:
	case TE_STREAM_FAMINE:
		ParseStream(type);
		break;

	case TE_LAVASPLASH:
		pos[0] = MSG_ReadCoord (net_message);
		pos[1] = MSG_ReadCoord (net_message);
		pos[2] = MSG_ReadCoord (net_message);
		R_LavaSplash (pos);
		break;

	case TE_TELEPORT:
		pos[0] = MSG_ReadCoord (net_message);
		pos[1] = MSG_ReadCoord (net_message);
		pos[2] = MSG_ReadCoord (net_message);
		R_TeleportSplash (pos);
		break;
/*	//jfm:not used
	case TE_EXPLOSION2:				// color mapped explosion
		pos[0] = MSG_ReadCoord (net_message);
		pos[1] = MSG_ReadCoord (net_message);
		pos[2] = MSG_ReadCoord (net_message);
		colorStart = MSG_ReadByte (net_message);
		colorLength = MSG_ReadByte (net_message);
		R_ParticleExplosion2 (pos, colorStart, colorLength);
		dl = CL_AllocDlight (0);
		VectorCopy (pos, dl->origin);
		dl->radius = 350;
		dl->die = cl.time + 0.5;
		dl->decay = 300;
		S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
		break;
*/
	default:
		Sys_Error ("CL_ParseTEnt: bad type");
	}
}
Пример #30
0
/*
 * ==============
 * Hunk_Print
 *
 * If "all" is specified, every single allocation is printed.
 * Otherwise, allocations with the same name will be totaled up before
 * printing.
 * ==============
 */
static void
Hunk_Print(qboolean all)
{
    hunk_t *h, *next, *endlow, *starthigh, *endhigh;
    int count, sum, pwidth;
    int totalblocks;
    char safename[HUNK_NAMELEN + 1]; /* Zero terminated copy of hunk name */

    count = 0;
    sum = 0;
    totalblocks = 0;
    memset(safename, 0, sizeof(safename));

    /* Don't put in wide spaces if not printing pointers */
    pwidth = all ? (sizeof(void *) * 2 + 2) : 8;

    h = (hunk_t *)hunk_base;
    endlow = (hunk_t *)(hunk_base + hunk_low_used);
    starthigh = (hunk_t *)(hunk_base + hunk_size - hunk_high_used);
    endhigh = (hunk_t *)(hunk_base + hunk_size);

    Con_Printf("%*s :%10i total hunk size\n", pwidth, "", hunk_size);
    Con_Printf("-------------------------\n");

    while (1) {
	/*
	 * skip to the high hunk if done with low hunk
	 */
	if (h == endlow) {
	    Con_Printf("-------------------------\n");
	    Con_Printf("%*s :%10i REMAINING\n", pwidth, "",
		       hunk_size - hunk_low_used - hunk_high_used);
	    Con_Printf("-------------------------\n");
	    h = starthigh;
	}
	/*
	 * if totally done, break
	 */
	if (h == endhigh)
	    break;

	/*
	 * run consistancy checks
	 */
	if (h->sentinal != HUNK_SENTINAL)
	    Sys_Error("%s: trashed sentinal", __func__);
	if (h->size < 16 || h->size + (byte *)h - hunk_base > hunk_size)
	    Sys_Error("%s: bad size", __func__);

	next = (hunk_t *)((byte *)h + h->size);
	count++;
	totalblocks++;
	sum += h->size;

	/*
	 * print the single block
	 */
	memcpy(safename, h->name, HUNK_NAMELEN);
	if (all)
	    Con_Printf("%*p :%10i %-*s\n", pwidth, h, h->size,
		       HUNK_NAMELEN, safename);

	/*
	 * print the total
	 */
	if (next == endlow || next == endhigh ||
	    strncmp(h->name, next->name, HUNK_NAMELEN)) {
	    if (!all)
		Con_Printf("%*s :%10i %-*s (TOTAL)\n", pwidth, "", sum,
			   HUNK_NAMELEN, safename);
	    count = 0;
	    sum = 0;
	}
	h = next;
    }
    Con_Printf("-------------------------\n");
    Con_Printf("%8i total blocks\n", totalblocks);
}