Ejemplo n.º 1
0
static void Handle_Key(unsigned char charcode, UInt32 mackeycode, qboolean keypressed)
{
	unsigned int keycode = 0;
	char ascii = '\0';

	switch (mackeycode)
	{
		case MK_ESCAPE:
			keycode = K_ESCAPE;
			break;
		case MK_F1:
			keycode = K_F1;
			break;
		case MK_F2:
			keycode = K_F2;
			break;
		case MK_F3:
			keycode = K_F3;
			break;
		case MK_F4:
			keycode = K_F4;
			break;
		case MK_F5:
			keycode = K_F5;
			break;
		case MK_F6:
			keycode = K_F6;
			break;
		case MK_F7:
			keycode = K_F7;
			break;
		case MK_F8:
			keycode = K_F8;
			break;
		case MK_F9:
			keycode = K_F9;
			break;
		case MK_F10:
			keycode = K_F10;
			break;
		case MK_F11:
			keycode = K_F11;
			break;
		case MK_F12:
			keycode = K_F12;
			break;
		case MK_SCROLLOCK:
			keycode = K_SCROLLOCK;
			break;
		case MK_PAUSE:
			keycode = K_PAUSE;
			break;
		case MK_BACKSPACE:
			keycode = K_BACKSPACE;
			break;
		case MK_INSERT:
			keycode = K_INS;
			break;
		case MK_HOME:
			keycode = K_HOME;
			break;
		case MK_PAGEUP:
			keycode = K_PGUP;
			break;
		case MK_NUMLOCK:
			keycode = K_NUMLOCK;
			break;
		case MK_KP_EQUALS:
			keycode = K_KP_EQUALS;
			break;
		case MK_KP_DIVIDE:
			keycode = K_KP_DIVIDE;
			break;
		case MK_KP_MULTIPLY:
			keycode = K_KP_MULTIPLY;
			break;
		case MK_TAB:
			keycode = K_TAB;
			break;
		case MK_DELETE:
			keycode = K_DEL;
			break;
		case MK_END:
			keycode = K_END;
			break;
		case MK_PAGEDOWN:
			keycode = K_PGDN;
			break;
		case MK_KP7:
			keycode = K_KP_7;
			break;
		case MK_KP8:
			keycode = K_KP_8;
			break;
		case MK_KP9:
			keycode = K_KP_9;
			break;
		case MK_KP_MINUS:
			keycode = K_KP_MINUS;
			break;
		case MK_CAPSLOCK:
			keycode = K_CAPSLOCK;
			break;
		case MK_RETURN:
			keycode = K_ENTER;
			break;
		case MK_KP4:
			keycode = K_KP_4;
			break;
		case MK_KP5:
			keycode = K_KP_5;
			break;
		case MK_KP6:
			keycode = K_KP_6;
			break;
		case MK_KP_PLUS:
			keycode = K_KP_PLUS;
			break;
		case MK_KP1:
			keycode = K_KP_1;
			break;
		case MK_KP2:
			keycode = K_KP_2;
			break;
		case MK_KP3:
			keycode = K_KP_3;
			break;
		case MK_KP_ENTER:
		case MK_IBOOK_ENTER:
			keycode = K_KP_ENTER;
			break;
		case MK_KP0:
			keycode = K_KP_0;
			break;
		case MK_KP_PERIOD:
			keycode = K_KP_PERIOD;
			break;
		default:
			switch(charcode)
			{
				case kUpArrowCharCode:
					keycode = K_UPARROW;
					break;
				case kLeftArrowCharCode:
					keycode = K_LEFTARROW;
					break;
				case kDownArrowCharCode:
					keycode = K_DOWNARROW;
					break;
				case kRightArrowCharCode:
					keycode = K_RIGHTARROW;
					break;
				case 0:
				case 191:
					// characters 0 and 191 are sent by the mouse buttons (?!)
					break;
				default:
					if ('A' <= charcode && charcode <= 'Z')
					{
						keycode = charcode + ('a' - 'A');  // lowercase it
						ascii = charcode;
					}
					else if (charcode >= 32)
					{
						keycode = charcode;
						ascii = charcode;
					}
					else
						Con_DPrintf(">> UNKNOWN char/keycode: %d/%u <<\n", charcode, (unsigned) mackeycode);
			}
	}

	if (keycode != 0)
		Key_Event(keycode, ascii, keypressed);
}
Ejemplo n.º 2
0
/*
================
ED_LoadFromFile

The entities are directly placed in the array, rather than allocated with
ED_Alloc, because otherwise an error loading the map would have entity
number references out of order.

Creates a server's entity / program execution context by
parsing textual entity definitions out of an ent file.

Used for both fresh maps and savegame loads.  A fresh map would also need
to call ED_CallSpawnFunctions () to let the objects initialize themselves.
================
*/
void ED_LoadFromFile (const char *data)
{	
	edict_t		*ent;
	int			inhibit;
	dfunction_t	*func;
	
	ent = NULL;
	inhibit = 0;
	pr_global_struct->time = sv.time;
	
// parse ents
	while (1)
	{
// parse the opening brace	
		data = COM_Parse (data);
		if (!data)
			break;
		if (com_token[0] != '{')
			Sys_Error ("ED_LoadFromFile: found %s when expecting {",com_token);

		if (!ent)
			ent = EDICT_NUM(0);
		else
			ent = ED_Alloc ();
		data = ED_ParseEdict (data, ent);

// remove things from different skill levels or deathmatch
		if (deathmatch.to_bool())
		{
			if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
			{
				ED_Free (ent);	
				inhibit++;
				continue;
			}
		}
		else if ((current_skill == 0 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_EASY))
				|| (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM))
				|| (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD)) )
		{
			ED_Free (ent);	
			inhibit++;
			continue;
		}

//
// immediately call spawn function
//
		if (!ent->v.classname)
		{
			Con_Printf ("No classname for:\n");
			ED_Print (ent);
			ED_Free (ent);
			continue;
		}

	// look for the spawn function
		func = ED_FindFunction ( pr_strings + ent->v.classname );

		if (!func)
		{
			Con_Printf ("No spawn function for:\n");
			ED_Print (ent);
			ED_Free (ent);
			continue;
		}

		pr_global_struct->self = EDICT_TO_PROG(ent);
		PR_ExecuteProgram (func - pr_functions);
	}	

	Con_DPrintf ("%i entities inhibited\n", inhibit);
}
Ejemplo n.º 3
0
/**
 * Generate a list of trifans or strips for the model, which holds for all frames
 */
void BuildTris(void) {
    int startv;
    int len, bestlen, besttype;
    int bestverts[1024];
    int besttris[1024];

    // build tristrips
    numorder = 0;
    numcommands = 0;
    memset(used, 0, sizeof (used));
    for (int i = 0; i < pheader->numtris; i++) {
        // pick an unused triangle and start the trifan
        if (used[i])
            continue;

        bestlen = 0;
        for (int type = 0; type < 2; type++) { //	type = 1;
            for (startv = 0; startv < 3; startv++) {
                if (type == 1)
                    len = StripLength(i, startv);
                else
                    len = FanLength(i, startv);

                if (len > bestlen) {
                    besttype = type;
                    bestlen = len;
                    for (int j = 0; j < bestlen + 2; j++)
                        bestverts[j] = stripverts[j];
                    for (int j = 0; j < bestlen; j++)
                        besttris[j] = striptris[j];
                }
            }
        }

        // mark the tris on the best strip as used
        for (int j = 0; j < bestlen; j++)
            used[besttris[j]] = 1;

        if (besttype == 1)
            commands[numcommands++] = (bestlen + 2);
        else
            commands[numcommands++] = -(bestlen + 2);

        for (int j = 0; j < bestlen + 2; j++) {
            // emit a vertex into the reorder buffer
            int k = bestverts[j];
            vertexorder[numorder++] = k;

            // emit s/t coords into the commands stream
            float s = stverts[k].s;
            float t = stverts[k].t;
            if (!triangles[besttris[0]].facesfront && stverts[k].onseam)
                s += pheader->skinwidth / 2; // on back side
            s = (s + 0.5) / pheader->skinwidth;
            t = (t + 0.5) / pheader->skinheight;

            *(float *)&commands[numcommands++] = s;
            *(float *)&commands[numcommands++] = t;
        }
    }

    commands[numcommands++] = 0; // end of list marker

    Con_DPrintf("%3i tri %3i vert %3i cmd\n", pheader->numtris, numorder, numcommands);

    allverts += numorder;
    alltris += pheader->numtris;
}
Ejemplo n.º 4
0
/*
=================
Mod_LoadTextures
=================
*/
void Mod_LoadTextures (lump_t *l)
{
// 1999-12-28 OpenGL fullbright fix by Neal White III  start
	// Neal White III - 12-28-1999 - OpenGL fullbright bugfix
	// [email protected]
	// http://home.telefragged.com/wally/
	//
	// Problem:
	//
	// There was a problem in the original glquake with fullbright texels.
	// In the software renderer, fullbrights glow brightly in the dark.
	// Essentially, the fullbrights were ignored.  I've fixed it by
	// adding another rendering pass and creating a new glowmap texture.
	//
	// Fix:
	//
	// When a texture with fullbright (FB) texels is loaded, a copy is made,
	// then the FB pixels are cleared to black in the original texture.  In
	// the copy, all normal colors are cleared and only the FBs remain.  When
	// it comes time to render the polygons, I do an additional pass and ADD
	// the glowmap on top of the current polygon.

	byte		*ptexel;
	qboolean	hasfullbrights;
//	qboolean	noglow = COM_CheckParm("-noglow");

//	int		i, j, pixels, num, max, altmax;
	int		i, num, max, altmax;
	unsigned long	j, pixels;
// 1999-12-28 OpenGL fullbright fix by Neal White III  end

	miptex_t	*mt;
	texture_t	*tx, *tx2;
	texture_t	*anims[10];
	texture_t	*altanims[10];
	dmiptexlump_t *m;

	if (!l->filelen)
	{
		loadmodel->textures = NULL;
		return;
	}
	m = (dmiptexlump_t *)(mod_base + l->fileofs);

	m->nummiptex = LittleLong (m->nummiptex);

	loadmodel->numtextures = m->nummiptex;
	loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof(*loadmodel->textures) , loadname);

	for (i=0 ; i<m->nummiptex ; i++)
	{
		m->dataofs[i] = LittleLong(m->dataofs[i]);
		if (m->dataofs[i] == -1)
			continue;
		mt = (miptex_t *)((byte *)m + m->dataofs[i]);
		mt->width = LittleLong (mt->width);
		mt->height = LittleLong (mt->height);
		for (j=0 ; j<MIPLEVELS ; j++)
			mt->offsets[j] = LittleLong (mt->offsets[j]);

		if ( (mt->width & 15) || (mt->height & 15) )
			Sys_Error ("Texture %s is not 16 aligned", mt->name);
		pixels = mt->width*mt->height/64*85;

// 1999-12-28 OpenGL fullbright fix by Neal White III  start
		hasfullbrights = false;

		if ((!strncmp(mt->name,"sky",3)) ||
				(!strncmp(mt->name,"*",1)) || 	// turbulent (liquid)
				(!gl_glowmap->value) || (! gl_mtexable) )
		{
			// sky has no lightmap, nor do liquids (so never needs a glowmap),
			// -noglow command line parameter, or no multi-texture support
			//
			// hasfullbrights is already false
		}
		else					// check this texture for fullbright texels
		{
			ptexel = (byte *)(mt+1);

			for (j=0 ; j<pixels ; j++)
			{
				if (ptexel[j] >= 256-32)	// 32 fullbright colors
				{
					hasfullbrights = true;
					break;
				}
			}
		}

		if (hasfullbrights)
		{
			tx = Hunk_AllocName (sizeof(texture_t) +pixels*2, loadname );
		}
		else
		{
// 1999-12-28 OpenGL fullbright fix by Neal White III  end
			tx = Hunk_AllocName (sizeof(texture_t) +pixels, loadname );
		}	// 1999-12-28 OpenGL fullbright fix by Neal White III

		loadmodel->textures[i] = tx;

		memcpy (tx->name, mt->name, sizeof(tx->name));
		tx->width = mt->width;
		tx->height = mt->height;
		for (j=0 ; j<MIPLEVELS ; j++)
		{	// 1999-12-28 OpenGL fullbright fix by Neal White III
			tx->offsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t);
// 1999-12-28 OpenGL fullbright fix by Neal White III  start
			if (hasfullbrights)
			{
				tx->glowoffsets[j] = mt->offsets[j] + sizeof(texture_t) - sizeof(miptex_t) + pixels;
			}
			else
			{
				tx->glowoffsets[j] = 0;
			}
		}
// 1999-12-28 OpenGL fullbright fix by Neal White III  end

		// the pixels immediately follow the structures
		memcpy ( tx+1, mt+1, pixels);

// 1999-12-28 OpenGL fullbright fix by Neal White III  start
		if (hasfullbrights)
		{
			ptexel = (byte *)(tx+1);
			memcpy ( ptexel+pixels, mt+1, pixels);
		}

		tx->flags = 0;
// 1999-12-28 OpenGL fullbright fix by Neal White III  end

		if (!strncmp(mt->name,"sky",3))
// 2000-07-09 Dedicated server bug in GLQuake fix by Nathan Cline  start
		{
			if (cls.state != ca_dedicated)
			{
// 2000-07-09 Dedicated server bug in GLQuake fix by Nathan Cline  end
				R_InitSky (tx);
// 2000-07-09 Dedicated server bug in GLQuake fix by Nathan Cline  start
			}
		}
// 2000-07-09 Dedicated server bug in GLQuake fix by Nathan Cline  end
		else
		{
			texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
// 1999-12-28 OpenGL fullbright fix by Neal White III  start
			// remove glowing fullbright colors from base texture (make black)
			if (hasfullbrights)
			{
#ifdef _DEBUG
				qboolean	bColorUsed[256];
				Con_DPrintf ("*** Fullbright Texture: \"%s\", %dx%d, %d pixels\n", mt->name, mt->width, mt->height, pixels);
				for (j=0 ; j<256 ; j++) bColorUsed[j] = false;
#endif

				ptexel = (byte *)(tx+1);

				for (j=0 ; j<pixels ; j++)
				{
#ifdef _DEBUG
					bColorUsed[ptexel[j]] = true;
#endif

					if (ptexel[j] >= 256-32)	// 32 fullbright colors
					{
						ptexel[j] = 0;		// make fullbrights black
					}
				}

#ifdef _DEBUG
				Con_DPrintf ("*** Normal colors: ");
				for (j=0 ; j<256-32 ; j++)
				{
					if (bColorUsed[j])
						Con_DPrintf ("%d ", j);
				}
				Con_DPrintf ("\n");

				Con_DPrintf ("*** Fullbrights: ");
				for (j=256-32 ; j<256 ; j++)
				{
					if (bColorUsed[j])
						Con_DPrintf ("%d ", j);
				}
				Con_DPrintf ("\n");
#endif
			}
#ifdef _DEBUG
			else
			{
				Con_DPrintf ("*** Normal Texture: \"%s\", %dx%d\n", mt->name, mt->width, mt->height);
			}
#endif
// 1999-12-28 OpenGL fullbright fix by Neal White III  end
			tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false);
// 1999-12-28 OpenGL fullbright fix by Neal White III  start
			// create glowmap texture (all black except for glowing fullbright colors)
			if (hasfullbrights)
			{
#ifdef _DEBUG
				qboolean bGlowDoubleCheck = false;
#endif
				char glowname[32];
				memcpy (glowname, mt->name, sizeof(mt->name));

				glowname[16] = '\0';
				for (j=0 ; glowname[j] != '\0'; j++)
					;
				glowname[j++] = '<';
				glowname[j++] = 'G';
				glowname[j++] = 'L';
				glowname[j++] = 'O';
				glowname[j++] = 'W';
				glowname[j++] = '>';
				glowname[j++] = '\0';

				ptexel = (byte *)(tx+1) + pixels;

				for (j=0 ; j<pixels ; j++)
				{
					if (ptexel[j] < 256-32)		// build glowmap
					{
						ptexel[j] = 0;			// make non-fullbrights black
					}
#ifdef _DEBUG
					else
					{
						bGlowDoubleCheck = true;
					}
#endif
				}
				tx->gl_glowtexnum = GL_LoadTexture (glowname, tx->width, tx->height, ptexel, true, false);
				tx->flags |= FLAG_HAS_GLOWMAP;

#ifdef _DEBUG
				if (! bGlowDoubleCheck)
					Con_DPrintf ("INTERNAL ERROR: Mod_LoadTextures - FullBright texture \"%s\" has no FullBright colors!\n", glowname);
#endif
			}
// 1999-12-28 OpenGL fullbright fix by Neal White III  end
			texture_mode = GL_LINEAR;
		}
	}

//
// sequence the animations
//
	for (i=0 ; i<m->nummiptex ; i++)
	{
		tx = loadmodel->textures[i];
		if (!tx || tx->name[0] != '+')
			continue;
		if (tx->anim_next)
			continue;	// already sequenced

	// find the number of frames in the animation
		memset (anims, 0, sizeof(anims));
		memset (altanims, 0, sizeof(altanims));

		max = tx->name[1];
		altmax = 0;
		if (max >= 'a' && max <= 'z')
			max -= 'a' - 'A';
		if (max >= '0' && max <= '9')
		{
			max -= '0';
			altmax = 0;
			anims[max] = tx;
			max++;
		}
		else if (max >= 'A' && max <= 'J')
		{
			altmax = max - 'A';
			max = 0;
			altanims[altmax] = tx;
			altmax++;
		}
		else
			Sys_Error ("Bad animating texture %s", tx->name);

		for (j=i+1 ; j<m->nummiptex ; j++)
		{
			tx2 = loadmodel->textures[j];
			if (!tx2 || tx2->name[0] != '+')
				continue;
			if (strcmp (tx2->name+2, tx->name+2))
				continue;

			num = tx2->name[1];
			if (num >= 'a' && num <= 'z')
				num -= 'a' - 'A';
			if (num >= '0' && num <= '9')
			{
				num -= '0';
				anims[num] = tx2;
				if (num+1 > max)
					max = num + 1;
			}
			else if (num >= 'A' && num <= 'J')
			{
				num = num - 'A';
				altanims[num] = tx2;
				if (num+1 > altmax)
					altmax = num+1;
			}
			else
				Sys_Error ("Bad animating texture %s", tx->name);
		}

#define	ANIM_CYCLE	2
	// link them all together
		for (j=0 ; j<max ; j++)
		{
			tx2 = anims[j];
			if (!tx2)
				Sys_Error ("Missing frame %i of %s",j, tx->name);
			tx2->anim_total = max * ANIM_CYCLE;
			tx2->anim_min = j * ANIM_CYCLE;
			tx2->anim_max = (j+1) * ANIM_CYCLE;
			tx2->anim_next = anims[ (j+1)%max ];
			if (altmax)
				tx2->alternate_anims = altanims[0];
		}
		for (j=0 ; j<altmax ; j++)
		{
			tx2 = altanims[j];
			if (!tx2)
				Sys_Error ("Missing frame %i of %s",j, tx->name);
			tx2->anim_total = altmax * ANIM_CYCLE;
			tx2->anim_min = j * ANIM_CYCLE;
			tx2->anim_max = (j+1) * ANIM_CYCLE;
			tx2->anim_next = altanims[ (j+1)%altmax ];
			if (max)
				tx2->alternate_anims = anims[0];
		}
	}
}
Ejemplo n.º 5
0
/*
================
BuildTris

Generate a list of trifans or strips
for the model, which holds for all frames
================
*/
void BuildTris (void)
{
	int		i, j, k;
	int		startv;
	mtriangle_t	*last, *check;
	int		m1, m2;
	int		striplength;
	trivertx_t	*v;
	mtriangle_t	*tv;
	float		s, t;
	int		index;
	int		len, bestlen, besttype;
	int		bestverts[1024];
	int		besttris[1024];
	int		type;
	int		stripmax = 0;

	//
	// build tristrips
	//
	numorder = 0;
	numcommands = 0;
	memset (used, 0, sizeof(used));
	for (i=0 ; i<pheader->numtris ; i++)
	{
		// pick an unused triangle and start the trifan
		if (used[i])
			continue;

		bestlen = 0;
		for (type = 0 ; type < 2 ; type++)
//	type = 1;
		{
			for (startv =0 ; startv < 3 ; startv++)
			{
				if (type == 1)
					len = StripLength (i, startv);
				else
					len = FanLength (i, startv);
				
				// Save peak
				if (len > stripmax)
					stripmax = len;

				if (len > bestlen)
				{
					besttype = type;
					bestlen = len;
					for (j=0 ; j<bestlen+2 ; j++)
						bestverts[j] = stripverts[j];
					for (j=0 ; j<bestlen ; j++)
						besttris[j] = striptris[j];
				}
			}
		}

		// mark the tris on the best strip as used
		for (j=0 ; j<bestlen ; j++)
			used[besttris[j]] = 1;

		ChkCmds ("BuildTris");

		if (besttype == 1)
			commands[numcommands++] = (bestlen+2);
		else
			commands[numcommands++] = -(bestlen+2);

		for (j=0 ; j<bestlen+2 ; j++)
		{
			// emit a vertex into the reorder buffer
			k = bestverts[j];
			vertexorder[numorder++] = k;

			// emit s/t coords into the commands stream
			s = stverts[k].s;
			t = stverts[k].t;
			if (!triangles[besttris[0]].facesfront && stverts[k].onseam)
				s += pheader->skinwidth / 2;	// on back side
			s = (s + 0.5) / pheader->skinwidth;
			t = (t + 0.5) / pheader->skinheight;

			ChkCmds ("BuildTris");

			*(float *)&commands[numcommands++] = s;
			*(float *)&commands[numcommands++] = t;
		}
	}

	ChkCmds ("BuildTris");

	commands[numcommands++] = 0;		// end of list marker

	// Check old limit
	if (stripmax + 2 >= 128)
	{
		Con_Printf ("\002BuildTris: ");
		Con_Printf ("excessive stripcount (%d, normal max = %d) in %s\n", stripmax, 128 - 2, aliasmodel->name);
	}

	// Check old limit
	if (numcommands >= 8192)
	{
		Con_Printf ("\002BuildTris: ");
		Con_Printf ("excessive commands (%d, normal max = %d) in %s\n", numcommands, 8192, aliasmodel->name);
	}

#ifndef NO_CACHE_MESH
	Con_DPrintf ("%3i tri %3i vert %3i cmd\n", pheader->numtris, numorder, numcommands);
#endif
}
Ejemplo n.º 6
0
int TCP_OpenListenSocket (unsigned short int port)
{
	int newsocket;
	struct sockaddr_in address = { 0 };
	unsigned long nonblocking = true;
	int i;

	if ((newsocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
		Con_Printf ("TCP_OpenListenSocket: socket: (%i): %s\n", qerrno, strerror(qerrno));
		return INVALID_SOCKET;
	}

#ifndef _WIN32
	if ((fcntl (newsocket, F_SETFL, O_NONBLOCK)) == -1) { // O'Rly?! @@@
		Con_Printf ("TCP_OpenListenSocket: fcntl: (%i): %s\n", qerrno, strerror(qerrno));
		closesocket(newsocket);
		return INVALID_SOCKET;
	}
#endif

	if (ioctlsocket (newsocket, FIONBIO, &nonblocking) == -1) { // make asynchronous
		Con_Printf ("TCP_OpenListenSocket: ioctl: (%i): %s\n", qerrno, strerror(qerrno));
		closesocket(newsocket);
		return INVALID_SOCKET;
	}

#ifdef __APPLE__
	address.sin_len = sizeof(address); // apple are special...
#endif
	address.sin_family = AF_INET;

	// check for interface binding option
	if ((i = COM_CheckParm("-ip")) != 0 && i < COM_Argc()) {
		address.sin_addr.s_addr = inet_addr(COM_Argv(i+1));
		Con_DPrintf ("Binding to IP Interface Address of %s\n", inet_ntoa(address.sin_addr));
	}
	else {
		address.sin_addr.s_addr = INADDR_ANY;
	}
	
	if (port == PORT_ANY) {
		address.sin_port = 0;
	}
	else {
		address.sin_port = htons(port);
	}

	if (bind (newsocket, (void *)&address, sizeof(address)) == -1) {
		Con_Printf ("TCP_OpenListenSocket: bind: (%i): %s\n", qerrno, strerror(qerrno));
		closesocket(newsocket);
		return INVALID_SOCKET;
	}

	if (listen (newsocket, TCP_LISTEN_BACKLOG) == INVALID_SOCKET) {
		Con_Printf ("TCP_OpenListenSocket: listen: (%i): %s\n", qerrno, strerror(qerrno));
		closesocket(newsocket);
		return INVALID_SOCKET;
	}

	if (!TCP_Set_KEEPALIVE(newsocket)) {
		Con_Printf ("TCP_OpenListenSocket: TCP_Set_KEEPALIVE: failed\n");
		closesocket(newsocket);
		return INVALID_SOCKET;
	}

	return newsocket;
}
Ejemplo n.º 7
0
//jpg loading
byte *LoadJPG (FILE *f)
{
    struct jpeg_decompress_struct cinfo;
    JDIMENSION num_scanlines;
    JSAMPARRAY in;
    struct jpeg_error_mgr jerr;
    int numPixels;
    int row_stride;
    byte *out;
    int count;
    int i;
    //int r, g, b;
    byte *image_rgba;

    // set up the decompression.
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress (&cinfo);

    // inititalize the source
    jpeg_stdio_src (&cinfo, f);

    // initialize decompression
    (void) jpeg_read_header (&cinfo, TRUE);
    (void) jpeg_start_decompress (&cinfo);

    numPixels = cinfo.image_width * cinfo.image_height;

    // initialize the input buffer - we'll use the in-built memory management routines in the
    // JPEG library because it will automatically free the used memory for us when we destroy
    // the decompression structure.  cool.
    row_stride = cinfo.output_width * cinfo.output_components;
    in = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

    // bit of error checking
    if (cinfo.output_components != 3)
        goto error;


    // initialize the return data
    image_rgba = malloc ((numPixels * 4));

    // read the jpeg
    count = 0;

    while (cinfo.output_scanline < cinfo.output_height) 
    {
        num_scanlines = jpeg_read_scanlines(&cinfo, in, 1);
        out = in[0];

        for (i = 0; i < row_stride;)
        {
            image_rgba[count++] = out[i++];//r
            image_rgba[count++] = out[i++];//g
            image_rgba[count++] = out[i++];//b
            image_rgba[count++] = 255;
        }
    }

    // finish decompression and destroy the jpeg
    image_width = cinfo.image_width;
    image_height = cinfo.image_height;

    (void) jpeg_finish_decompress (&cinfo);
    jpeg_destroy_decompress (&cinfo);

    fclose (f);
    return image_rgba;

error:
    // this should rarely (if ever) happen, but just in case...
    Con_DPrintf ("Invalid JPEG Format\n");
    jpeg_destroy_decompress (&cinfo);

    fclose (f);
    return NULL;
}
Ejemplo n.º 8
0
int	Datagram_GetMessage(qsocket_t *sock)
{
    unsigned int	length;
    unsigned int	flags;
    int				ret = 0;
    struct qsockaddr readaddr;
    unsigned int	sequence;
    unsigned int	count;

    if (!sock->canSend)
        if ((net_time - sock->lastSendTime) > 1.0) {
            ReSendMessage(sock);
        }

    while (1) {
        length = sfunc.Read(sock->socket, (byte *)&packetBuffer, NET_DATAGRAMSIZE, &readaddr);

//	if ((rand() & 255) > 220)
//		continue;

        if (length == 0) {
            break;
        }

        if (length == -1) {
            Con_Printf("Read error\n");
            return -1;
        }

        if (sfunc.AddrCompare(&readaddr, &sock->addr) != 0) {
#ifdef DEBUG
            Con_DPrintf("Forged packet received\n");
            Con_DPrintf("Expected: %s\n", StrAddr(&sock->addr));
            Con_DPrintf("Received: %s\n", StrAddr(&readaddr));
#endif
            continue;
        }

        if (length < NET_HEADERSIZE) {
            shortPacketCount++;
            continue;
        }

        length = BigLong(packetBuffer.length);
        flags = length & (~NETFLAG_LENGTH_MASK);
        length &= NETFLAG_LENGTH_MASK;

        if (flags & NETFLAG_CTL) {
            continue;
        }

        sequence = BigLong(packetBuffer.sequence);
        packetsReceived++;

        if (flags & NETFLAG_UNRELIABLE) {
            if (sequence < sock->unreliableReceiveSequence) {
                Con_DPrintf("Got a stale datagram\n");
                ret = 0;
                break;
            }
            if (sequence != sock->unreliableReceiveSequence) {
                count = sequence - sock->unreliableReceiveSequence;
                droppedDatagrams += count;
                Con_DPrintf("Dropped %u datagram(s)\n", count);
            }
            sock->unreliableReceiveSequence = sequence + 1;

            length -= NET_HEADERSIZE;

            SZ_Clear(&net_message);
            SZ_Write(&net_message, packetBuffer.data, length);

            ret = 2;
            break;
        }

        if (flags & NETFLAG_ACK) {
            if (sequence != (sock->sendSequence - 1)) {
                Con_DPrintf("Stale ACK received\n");
                continue;
            }
            if (sequence == sock->ackSequence) {
                sock->ackSequence++;
                if (sock->ackSequence != sock->sendSequence) {
                    Con_DPrintf("ack sequencing error\n");
                }
            } else {
                Con_DPrintf("Duplicate ACK received\n");
                continue;
            }
            sock->sendMessageLength -= MAX_DATAGRAM;
            if (sock->sendMessageLength > 0) {
                Q_memcpy(sock->sendMessage, sock->sendMessage+MAX_DATAGRAM, sock->sendMessageLength);
                sock->sendNext = true;
            } else {
                sock->sendMessageLength = 0;
                sock->canSend = true;
            }
            continue;
        }

        if (flags & NETFLAG_DATA) {
            packetBuffer.length = BigLong(NET_HEADERSIZE | NETFLAG_ACK);
            packetBuffer.sequence = BigLong(sequence);
            sfunc.Write(sock->socket, (byte *)&packetBuffer, NET_HEADERSIZE, &readaddr);

            if (sequence != sock->receiveSequence) {
                receivedDuplicateCount++;
                continue;
            }
            sock->receiveSequence++;

            length -= NET_HEADERSIZE;

            if (flags & NETFLAG_EOM) {
                SZ_Clear(&net_message);
                SZ_Write(&net_message, sock->receiveMessage, sock->receiveMessageLength);
                SZ_Write(&net_message, packetBuffer.data, length);
                sock->receiveMessageLength = 0;

                ret = 1;
                break;
            }

            Q_memcpy(sock->receiveMessage + sock->receiveMessageLength, packetBuffer.data, length);
            sock->receiveMessageLength += length;
            continue;
        }
    }

    if (sock->sendNext) {
        SendMessageNext(sock);
    }

    return ret;
}
Ejemplo n.º 9
0
int WINS_Init (void)
{
#ifdef ID_PC
	int		i;
	char	buff[MAXHOSTNAMELEN];
	char	*p;
	int		r;
	WORD	wVersionRequested;
	HINSTANCE hInst;

// initialize the Winsock function vectors (we do this instead of statically linking
// so we can run on Win 3.1, where there isn't necessarily Winsock)
    hInst = LoadLibrary("wsock32.dll");
	
	if (hInst == NULL)
	{
		Con_SafePrintf ("Failed to load winsock.dll\n");
		winsock_lib_initialized = false;
		return -1;
	}

	winsock_lib_initialized = true;

    pWSAStartup = (int (__stdcall *)(WORD,LPWSADATA))GetProcAddress(hInst, "WSAStartup");
    pWSACleanup = (int (__stdcall *)(void))GetProcAddress(hInst, "WSACleanup");
    pWSAGetLastError = (int (__stdcall *)(void))GetProcAddress(hInst, "WSAGetLastError");
    psocket = (SOCKET (__stdcall *)(int,int,int))GetProcAddress(hInst, "socket");
    pioctlsocket = (int (__stdcall *)(SOCKET,long,u_long *))GetProcAddress(hInst, "ioctlsocket");
    psetsockopt = (int (__stdcall *)(SOCKET,int,int,const char *,int))GetProcAddress(hInst, "setsockopt");
    precvfrom = (int (__stdcall *)(SOCKET,char *,int,int,sockaddr *,int *))GetProcAddress(hInst, "recvfrom");
    psendto = (int (__stdcall *)(SOCKET,const char *,int,int,const sockaddr *,int))GetProcAddress(hInst, "sendto");
    pclosesocket = (int (__stdcall *)(SOCKET))GetProcAddress(hInst, "closesocket");
    pgethostname = (int (__stdcall *)(char *,int))GetProcAddress(hInst, "gethostname");
    pgethostbyname = (hostent *(__stdcall *)(const char *))GetProcAddress(hInst, "gethostbyname");
    pgethostbyaddr = (hostent *(__stdcall *)(const char *,int,int))GetProcAddress(hInst, "gethostbyaddr");
    pgetsockname = (int (__stdcall *)(SOCKET,sockaddr *,int *))GetProcAddress(hInst, "getsockname");

    if (!pWSAStartup || !pWSACleanup || !pWSAGetLastError ||
		!psocket || !pioctlsocket || !psetsockopt ||
		!precvfrom || !psendto || !pclosesocket ||
		!pgethostname || !pgethostbyname || !pgethostbyaddr ||
		!pgetsockname)
	{
		Con_SafePrintf ("Couldn't GetProcAddress from winsock.dll\n");
		return -1;
	}

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

	if (winsock_initialized == 0)
	{
		wVersionRequested = MAKEWORD(1, 1); 

		r = pWSAStartup (MAKEWORD(1, 1), &winsockdata);

		if (r)
		{
			Con_SafePrintf ("Winsock initialization failed.\n");
			return -1;
		}
	}
	winsock_initialized++;

	// determine my name
	if (pgethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR)
	{
		Con_DPrintf ("Winsock TCP/IP Initialization failed.\n");
		if (--winsock_initialized == 0)
			pWSACleanup ();
		return -1;
	}

	// if the quake hostname isn't set, set it to the machine name
	if (Q_strcmp(hostname.string, "UNNAMED") == 0)
	{
		// see if it's a text IP address (well, close enough)
		for (p = buff; *p; p++)
			if ((*p < '0' || *p > '9') && *p != '.')
				break;

		// if it is a real name, strip off the domain; we only want the host
		if (*p)
		{
			for (i = 0; i < 15; i++)
				if (buff[i] == '.')
					break;
			buff[i] = 0;
		}
		Cvar_Set ("hostname", buff);
	}

	i = COM_CheckParm ("-ip");
	if (i)
	{
		if (i < com_argc-1)
		{
			myAddr = inet_addr(com_argv[i+1]);
			if (myAddr == INADDR_NONE)
				Sys_Error ("%s is not a valid IP address", com_argv[i+1]);
			strcpy(my_tcpip_address, com_argv[i+1]);
		}
		else
		{
			Sys_Error ("NET_Init: you must specify an IP address after -ip");
		}
	}
	else
	{
		myAddr = INADDR_ANY;
		strcpy(my_tcpip_address, "INADDR_ANY");
	}

	if ((net_controlsocket = WINS_OpenSocket (0)) == -1)
	{
		Con_Printf("WINS_Init: Unable to open control socket\n");
		if (--winsock_initialized == 0)
			pWSACleanup ();
		return -1;
	}

	((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET;
	((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;
	((struct sockaddr_in *)&broadcastaddr)->sin_port = htons((unsigned short)net_hostport);

	Con_Printf("Winsock TCP/IP Initialized\n");
	tcpipAvailable = true;

	return net_controlsocket;
#endif
	return 0;
}
Ejemplo n.º 10
0
/*
==================
CL_ParsePacketEntities

An svc_packetentities has just been parsed, deal with the
rest of the data stream.
==================
*/
void CL_ParsePacketEntities (qboolean delta)
{
	int			oldpacket, newpacket;
	packet_entities_t	*oldp, *newp, dummy;
	int			oldindex, newindex;
	int			word, newnum, oldnum;
	qboolean	full;
	byte		from;

	newpacket = cls.netchan.incoming_sequence&UPDATE_MASK;
	newp = &cl.frames[newpacket].packet_entities;
	cl.frames[newpacket].invalid = false;

	if (delta)
	{
		from = MSG_ReadByte ();

		oldpacket = cl.frames[newpacket].delta_sequence;

		if ( (from&UPDATE_MASK) != (oldpacket&UPDATE_MASK) )
			Con_DPrintf ("WARNING: from mismatch\n");
	}
	else
		oldpacket = -1;

	full = false;
	if (oldpacket != -1)
	{
		if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP-1)
		{	// we can't use this, it is too old
			FlushEntityPacket ();
			return;
		}
		cl.validsequence = cls.netchan.incoming_sequence;
		oldp = &cl.frames[oldpacket&UPDATE_MASK].packet_entities;
	}
	else
	{	// this is a full update that we can start delta compressing from now
		oldp = &dummy;
		dummy.num_entities = 0;
		cl.validsequence = cls.netchan.incoming_sequence;
		full = true;
	}

	oldindex = 0;
	newindex = 0;
	newp->num_entities = 0;

	while (1)
	{
		word = (unsigned short)MSG_ReadShort ();
		if (msg_badread)
		{	// something didn't parse right...
			Host_EndGame ("msg_badread in packetentities");
			return;
		}

		if (!word)
		{
			while (oldindex < oldp->num_entities)
			{	// copy all the rest of the entities from the old packet
//Con_Printf ("copy %i\n", oldp->entities[oldindex].number);
				if (newindex >= MAX_PACKET_ENTITIES)
					Host_EndGame ("CL_ParsePacketEntities: newindex == MAX_PACKET_ENTITIES");
				newp->entities[newindex] = oldp->entities[oldindex];
				newindex++;
				oldindex++;
			}
			break;
		}
		newnum = word&511;
		oldnum = oldindex >= oldp->num_entities ? 9999 : oldp->entities[oldindex].number;

		while (newnum > oldnum)
		{
			if (full)
			{
				Con_Printf ("WARNING: oldcopy on full update");
				FlushEntityPacket ();
				return;
			}

//Con_Printf ("copy %i\n", oldnum);
			// copy one of the old entities over to the new packet unchanged
			if (newindex >= MAX_PACKET_ENTITIES)
				Host_EndGame ("CL_ParsePacketEntities: newindex == MAX_PACKET_ENTITIES");
			newp->entities[newindex] = oldp->entities[oldindex];
			newindex++;
			oldindex++;
			oldnum = oldindex >= oldp->num_entities ? 9999 : oldp->entities[oldindex].number;
		}

		if (newnum < oldnum)
		{	// new from baseline
//Con_Printf ("baseline %i\n", newnum);
			if (word & U_REMOVE)
			{
				if (full)
				{
					cl.validsequence = 0;
					Con_Printf ("WARNING: U_REMOVE on full update\n");
					FlushEntityPacket ();
					return;
				}
				continue;
			}
			if (newindex >= MAX_PACKET_ENTITIES)
				Host_EndGame ("CL_ParsePacketEntities: newindex == MAX_PACKET_ENTITIES");
			CL_ParseDelta (&cl_baselines[newnum], &newp->entities[newindex], word);
			newindex++;
			continue;
		}

		if (newnum == oldnum)
		{	// delta from previous
			if (full)
			{
				cl.validsequence = 0;
				Con_Printf ("WARNING: delta on full update");
			}
			if (word & U_REMOVE)
			{
				oldindex++;
				continue;
			}
//Con_Printf ("delta %i\n",newnum);
			CL_ParseDelta (&oldp->entities[oldindex], &newp->entities[newindex], word);
			newindex++;
			oldindex++;
		}

	}

	newp->num_entities = newindex;
}
Ejemplo n.º 11
0
/*
==============
S_LoadSound
==============
*/
sfxcache_t *S_LoadSound(sfx_t *s)
{
    char	namebuffer[256];
    byte	*data;
    wavinfo_t	info;
    int		len;
    float	stepscale;
    sfxcache_t	*sc;
    byte	stackbuf[1*1024];		// avoid dirtying the cache heap
    loadedfile_t	*fileinfo;	// 2001-09-12 Returning information about loaded file by Maddes

// see if still in memory
    sc = Cache_Check(&s->cache);
    if (sc) {
        return sc;
    }

//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf);
// load it in
    Q_strcpy(namebuffer, "sound/");
    Q_strcat(namebuffer, s->name);

    if (developer.value == 1) {
        Con_DPrintf("Loading %s\n",namebuffer);    // Edited
    }
//	Con_Printf ("loading %s\n",namebuffer);

// 2001-09-12 Returning information about loaded file by Maddes  start
    /*
    	data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf));

    	if (!data)
    */
    fileinfo = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf));
    if (!fileinfo)
// 2001-09-12 Returning information about loaded file by Maddes  end
    {
        Con_Printf("Couldn't load %s\n", namebuffer);
        return NULL;
    }
    data = fileinfo->data;	// 2001-09-12 Returning information about loaded file by Maddes

    info = GetWavinfo(s->name, data, com_filesize);
    if (info.channels != 1) {
        Con_Printf("%s is a stereo sample\n",s->name);
        return NULL;
    }

    stepscale = (float)info.rate / shm->speed;
    len = info.samples / stepscale;

    len = len * info.width * info.channels;

    sc = Cache_Alloc(&s->cache, len + sizeof(sfxcache_t), s->name);
    if (!sc) {
        return NULL;
    }

    sc->length = info.samples;
    sc->loopstart = info.loopstart;
    sc->speed = info.rate;
    sc->width = info.width;
    sc->stereo = info.channels;

    ResampleSfx(s, sc->speed, sc->width, data + info.dataofs);

    return sc;
}
Ejemplo n.º 12
0
qboolean SND_FOpen (const char *name, qboolean midi, qboolean resume)
{
	int len;
	char file[MAX_QPATH];
	char filefull[MAX_QPATH];
	FILE	*f;


	if(resume == true)
	{
		strcpy(file, name);
	}
	else
	{
		if (midi == true)
			sprintf(file, "midi/%s", name);
		else
			sprintf(file, "mod/%s", name);
	}


	if(midi == true)
	{
		sprintf(filefull, "%s.mid", file);
		len = COM_FOpenFile ((char *)filefull, &f);
	}
	else
	{
		sprintf(filefull, "%s.ogg", file);
		len = COM_FOpenFile ((char *)filefull, &f);
		if(len < 1)
		{
			sprintf(filefull, "%s.mp3", file);
			len = COM_FOpenFile ((char *)filefull, &f);
		}
		if(len < 1)
		{
			sprintf(filefull, "%s.wav", file);
			len = COM_FOpenFile ((char *)filefull, &f);
		}
	}


	if(len < 1)
	{
		Con_Printf("SND_FOpen: Failed to open %s, file not found\n", filefull);
		return false;
	}

	if(!SND_File.length)
	{
		strcpy(SND_File.filename, filefull);
		SND_File.length = len;
		SND_File.data = COM_FReadFile(f, len);

		Con_DPrintf("SND_FOpen: Sucessfully opened %s\n", filefull);
		return true;
	}

	Con_SafePrintf("SND_FOpen: Failed to open %s, insufficient handles\n", filefull);
	return false;
}
Ejemplo n.º 13
0
/*
===================
SV_ReadClientMessage

Returns false if the client should be killed
===================
*/
qboolean SV_ReadClientMessage (void)
{
	int		ret;
	int		cmd;
	char		*s;
	
	do
	{
nextmsg:
		ret = NET_GetMessage (host_client->netconnection);
		if (ret == -1)
		{
			Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n");
			return false;
		}
		if (!ret)
			return true;
					
		MSG_BeginReading (net_message);
		
		while (1)
		{
			if (!host_client->active)
				return false;	// a command caused an error

			if (net_message->badread)
			{
				Sys_Printf ("SV_ReadClientMessage: badread\n");
				return false;
			}	
	
			cmd = MSG_ReadChar (net_message);
			
			switch (cmd)
			{
			case -1:
				goto nextmsg;		// end of message
				
			default:
				Sys_Printf ("SV_ReadClientMessage: unknown command char\n");
				return false;
							
			case clc_nop:
//				Sys_Printf ("SV_ReadClientMessage: clc_nop\n");
				break;
				
			case clc_stringcmd:	
				s = MSG_ReadString (net_message);

				ret = 0;

				if (nehahra)
				{
					if (strncasecmp(s, "max", 3) == 0)
						ret = 1;
					else if (strncasecmp(s, "monster", 7) == 0)
						ret = 1;
					else if (strncasecmp(s, "scrag", 5) == 0)
						ret = 1;
					else if (strncasecmp(s, "wraith", 6) == 0)
						ret = 1;
					else if (strncasecmp(s, "gimme", 5) == 0)
						ret = 1;
				}
				else
				{
					if (strncasecmp(s, "god", 3) == 0)
						ret = 1;
					else if (strncasecmp(s, "notarget", 8) == 0)
						ret = 1;
					else if (strncasecmp(s, "fly", 3) == 0)
						ret = 1;
					else if (strncasecmp(s, "noclip", 6) == 0)
						ret = 1;
					else if (strncasecmp(s, "give", 4) == 0)
						ret = 1;
				}

				if (strncasecmp(s, "status", 6) == 0)
					ret = 1;
				else if (strncasecmp(s, "freezeall", 9) == 0)
					ret = 1;
				else if (strncasecmp(s, "name", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "say", 3) == 0)
					ret = 1;
				else if (strncasecmp(s, "say_team", 8) == 0)
					ret = 1;
				else if (strncasecmp(s, "tell", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "color", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "kill", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "pause", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "spawn", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "begin", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "prespawn", 8) == 0)
					ret = 1;
				else if (strncasecmp(s, "kick", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "ping", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "ban", 3) == 0)
					ret = 1;
				else if (strncasecmp(s, "qcexec", 6) == 0)
					ret = 1; // qcexec command for qc testing

				if (ret == 1)
					Cmd_ExecuteString (s, src_client);
				else
					Con_DPrintf("%s tried to %s\n", host_client->name, s);
				break;
				
			case clc_disconnect:
//				Sys_Printf ("SV_ReadClientMessage: client disconnected\n");
				return false;
			
			case clc_move:
				SV_ReadClientMove (&host_client->cmd);
				break;
			}
		}
	} while (ret == 1);
	
	return true;
}
Ejemplo n.º 14
0
void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecursor)
{
	if (!mouse_avail || !window)
		relative = hidecursor = false;

	if (relative)
	{
		if(vid_usingmouse && (vid_usingnoaccel != !!apple_mouse_noaccel.integer))
			VID_SetMouse(false, false, false); // ungrab first!
		if (!vid_usingmouse)
		{
			Rect winBounds;
			CGPoint winCenter;

			SelectWindow(window);

			// Put the mouse cursor at the center of the window
			GetWindowBounds (window, kWindowContentRgn, &winBounds);
			winCenter.x = (winBounds.left + winBounds.right) / 2;
			winCenter.y = (winBounds.top + winBounds.bottom) / 2;
			CGWarpMouseCursorPosition(winCenter);

			// Lock the mouse pointer at its current position
			CGAssociateMouseAndMouseCursorPosition(false);

			// Save the status of mouse acceleration
			originalMouseSpeed = -1.0; // in case of error
			if(apple_mouse_noaccel.integer)
			{
				io_connect_t mouseDev = IN_GetIOHandle();
				if(mouseDev != 0)
				{
					if(IOHIDGetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), &originalMouseSpeed) == kIOReturnSuccess)
					{
						Con_DPrintf("previous mouse acceleration: %f\n", originalMouseSpeed);
						if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), -1.0) != kIOReturnSuccess)
						{
							Con_Print("Could not disable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
							Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
						}
					}
					else
					{
						Con_Print("Could not disable mouse acceleration (failed at IOHIDGetAccelerationWithKey).\n");
						Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
					}
					IOServiceClose(mouseDev);
				}
				else
				{
					Con_Print("Could not disable mouse acceleration (failed at IO_GetIOHandle).\n");
					Cvar_SetValueQuick(&apple_mouse_noaccel, 0);
				}
			}

			vid_usingmouse = true;
			vid_usingnoaccel = !!apple_mouse_noaccel.integer;
		}
	}
	else
	{
		if (vid_usingmouse)
		{
			if(originalMouseSpeed != -1.0)
			{
				io_connect_t mouseDev = IN_GetIOHandle();
				if(mouseDev != 0)
				{
					Con_DPrintf("restoring mouse acceleration to: %f\n", originalMouseSpeed);
					if(IOHIDSetAccelerationWithKey(mouseDev, CFSTR(kIOHIDMouseAccelerationType), originalMouseSpeed) != kIOReturnSuccess)
						Con_Print("Could not re-enable mouse acceleration (failed at IOHIDSetAccelerationWithKey).\n");
					IOServiceClose(mouseDev);
				}
				else
					Con_Print("Could not re-enable mouse acceleration (failed at IO_GetIOHandle).\n");
			}

			CGAssociateMouseAndMouseCursorPosition(true);

			vid_usingmouse = false;
		}
	}

	if (vid_usinghidecursor != hidecursor)
	{
		vid_usinghidecursor = hidecursor;
		if (hidecursor)
			CGDisplayHideCursor(CGMainDisplayID());
		else
			CGDisplayShowCursor(CGMainDisplayID());
	}
}
Ejemplo n.º 15
0
/*
=====================
SV_DropClient

Called when the player is getting totally kicked off the host
if (crash = true), don't bother sending signofs
=====================
*/
void SV_DropClient(qboolean crash)
{
	prvm_prog_t *prog = SVVM_prog;
	int i;
	Con_Printf("Client \"%s\" dropped\n", host_client->name);

	SV_StopDemoRecording(host_client);

	// make sure edict is not corrupt (from a level change for example)
	host_client->edict = PRVM_EDICT_NUM(host_client - svs.clients + 1);

	if (host_client->netconnection)
	{
		// tell the client to be gone
		if (!crash)
		{
			// LordHavoc: no opportunity for resending, so use unreliable 3 times
			unsigned char bufdata[8];
			sizebuf_t buf;
			memset(&buf, 0, sizeof(buf));
			buf.data = bufdata;
			buf.maxsize = sizeof(bufdata);
			MSG_WriteByte(&buf, svc_disconnect);
			NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, false);
			NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, false);
			NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, false);
		}
	}

	// call qc ClientDisconnect function
	// LordHavoc: don't call QC if server is dead (avoids recursive
	// Host_Error in some mods when they run out of edicts)
	if (host_client->clientconnectcalled && sv.active && host_client->edict)
	{
		// call the prog function for removing a client
		// this will set the body to a dead frame, among other things
		int saveSelf = PRVM_serverglobaledict(self);
		host_client->clientconnectcalled = false;
		PRVM_serverglobalfloat(time) = sv.time;
		PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(host_client->edict);
		prog->ExecuteProgram(prog, PRVM_serverfunction(ClientDisconnect), "QC function ClientDisconnect is missing");
		PRVM_serverglobaledict(self) = saveSelf;
	}

	if (host_client->netconnection)
	{
		// break the net connection
		NetConn_Close(host_client->netconnection);
		host_client->netconnection = NULL;
	}

	// if a download is active, close it
	if (host_client->download_file)
	{
		Con_DPrintf("Download of %s aborted when %s dropped\n", host_client->download_name, host_client->name);
		FS_Close(host_client->download_file);
		host_client->download_file = NULL;
		host_client->download_name[0] = 0;
		host_client->download_expectedposition = 0;
		host_client->download_started = false;
	}

	// remove leaving player from scoreboard
	host_client->name[0] = 0;
	host_client->colors = 0;
	host_client->frags = 0;
	// send notification to all clients
	// get number of client manually just to make sure we get it right...
	i = host_client - svs.clients;
	MSG_WriteByte (&sv.reliable_datagram, svc_updatename);
	MSG_WriteByte (&sv.reliable_datagram, i);
	MSG_WriteString (&sv.reliable_datagram, host_client->name);
	MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
	MSG_WriteByte (&sv.reliable_datagram, i);
	MSG_WriteByte (&sv.reliable_datagram, host_client->colors);
	MSG_WriteByte (&sv.reliable_datagram, svc_updatefrags);
	MSG_WriteByte (&sv.reliable_datagram, i);
	MSG_WriteShort (&sv.reliable_datagram, host_client->frags);

	// free the client now
	if (host_client->entitydatabase)
		EntityFrame_FreeDatabase(host_client->entitydatabase);
	if (host_client->entitydatabase4)
		EntityFrame4_FreeDatabase(host_client->entitydatabase4);
	if (host_client->entitydatabase5)
		EntityFrame5_FreeDatabase(host_client->entitydatabase5);

	if (sv.active)
	{
		// clear a fields that matter to DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS, and also frags
		PRVM_ED_ClearEdict(prog, host_client->edict);
	}

	// clear the client struct (this sets active to false)
	memset(host_client, 0, sizeof(*host_client));

	// update server listing on the master because player count changed
	// (which the master uses for filtering empty/full servers)
	NetConn_Heartbeat(1);

	if (sv.loadgame)
	{
		for (i = 0;i < svs.maxclients;i++)
			if (svs.clients[i].active && !svs.clients[i].spawned)
				break;
		if (i == svs.maxclients)
		{
			Con_Printf("Loaded game, everyone rejoined - unpausing\n");
			sv.paused = sv.loadgame = false; // we're basically done with loading now
		}
	}
}
Ejemplo n.º 16
0
int LHNET_Read(lhnetsocket_t *lhnetsocket, void *content, int maxcontentlength, lhnetaddress_t *vaddress)
{
	lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;
	int value = 0;
	if (!lhnetsocket || !address || !content || maxcontentlength < 1)
		return -1;
	if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_LOOP)
	{
		time_t currenttime;
		lhnetpacket_t *p, *pnext;
		// scan for any old packets to timeout while searching for a packet
		// that is waiting to be delivered to this socket
		currenttime = time(NULL);
		for (p = lhnet_packetlist.next;p != &lhnet_packetlist;p = pnext)
		{
			pnext = p->next;
			if (p->timeout < currenttime)
			{
				// unlink and free
				p->next->prev = p->prev;
				p->prev->next = p->next;
				Z_Free(p);
				continue;
			}
#ifndef STANDALONETEST
			if (cl_netlocalping.value && (realtime - cl_netlocalping.value * (1.0 / 2000.0)) < p->sentdoubletime)
				continue;
#endif
			if (value == 0 && p->destinationport == lhnetsocket->address.port)
			{
				if (p->length <= maxcontentlength)
				{
					lhnetaddressnative_t *localaddress = (lhnetaddressnative_t *)&lhnetsocket->address;
					*address = *localaddress;
					address->port = p->sourceport;
					memcpy(content, p->data, p->length);
					value = p->length;
				}
				else
					value = -1;
				// unlink and free
				p->next->prev = p->prev;
				p->prev->next = p->next;
				Z_Free(p);
			}
		}
	}
	else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET4)
	{
		SOCKLEN_T inetaddresslength;
		address->addresstype = LHNETADDRESSTYPE_NONE;
		inetaddresslength = sizeof(address->addr.in);
		value = recvfrom(lhnetsocket->inetsocket, (char *)content, maxcontentlength, LHNET_RECVFROM_FLAGS, &address->addr.sock, &inetaddresslength);
		if (value > 0)
		{
			address->addresstype = LHNETADDRESSTYPE_INET4;
			address->port = ntohs(address->addr.in.sin_port);
			return value;
		}
		else if (value < 0)
		{
			int e = SOCKETERRNO;
			if (e == EWOULDBLOCK)
				return 0;
			switch (e)
			{
				case ECONNREFUSED:
					Con_Print("Connection refused\n");
					return 0;
			}
			Con_DPrintf("LHNET_Read: recvfrom returned error: %s\n", LHNETPRIVATE_StrError());
		}
	}
#ifndef NOSUPPORTIPV6
	else if (lhnetsocket->address.addresstype == LHNETADDRESSTYPE_INET6)
	{
		SOCKLEN_T inetaddresslength;
		address->addresstype = LHNETADDRESSTYPE_NONE;
		inetaddresslength = sizeof(address->addr.in6);
		value = recvfrom(lhnetsocket->inetsocket, (char *)content, maxcontentlength, LHNET_RECVFROM_FLAGS, &address->addr.sock, &inetaddresslength);
		if (value > 0)
		{
			address->addresstype = LHNETADDRESSTYPE_INET6;
			address->port = ntohs(address->addr.in6.sin6_port);
			return value;
		}
		else if (value == -1)
		{
			int e = SOCKETERRNO;
			if (e == EWOULDBLOCK)
				return 0;
			switch (e)
			{
				case ECONNREFUSED:
					Con_Print("Connection refused\n");
					return 0;
			}
			Con_DPrintf("LHNET_Read: recvfrom returned error: %s\n", LHNETPRIVATE_StrError());
		}
	}
#endif
	return value;
}
Ejemplo n.º 17
0
void Host_Main(void)
{
	double time1 = 0;
	double time2 = 0;
	double time3 = 0;
	double cl_timer = 0, sv_timer = 0;
	double clframetime, deltacleantime, olddirtytime, dirtytime;
	double wait;
	int pass1, pass2, pass3, i;
	char vabuf[1024];
	qboolean playing;

	Host_Init();

	realtime = 0;
	dirtytime = Sys_DirtyTime();
	for (;;)
	{
		if (setjmp(host_abortframe))
		{
			SCR_ClearLoadingScreen(false);
			continue;			// something bad happened, or the server disconnected
		}

		olddirtytime = host_dirtytime;
		dirtytime = Sys_DirtyTime();
		deltacleantime = dirtytime - olddirtytime;
		if (deltacleantime < 0)
		{
			// warn if it's significant
			if (deltacleantime < -0.01)
				Con_Printf("Host_Mingled: time stepped backwards (went from %f to %f, difference %f)\n", olddirtytime, dirtytime, deltacleantime);
			deltacleantime = 0;
		}
		else if (deltacleantime >= 1800)
		{
			Con_Printf("Host_Mingled: time stepped forward (went from %f to %f, difference %f)\n", olddirtytime, dirtytime, deltacleantime);
			deltacleantime = 0;
		}
		realtime += deltacleantime;
		host_dirtytime = dirtytime;

		cl_timer += deltacleantime;
		sv_timer += deltacleantime;

		if (!svs.threaded)
		{
			svs.perf_acc_realtime += deltacleantime;

			// Look for clients who have spawned
			playing = false;
			for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
				if(host_client->spawned)
					if(host_client->netconnection)
						playing = true;
			if(sv.time < 10)
			{
				// don't accumulate time for the first 10 seconds of a match
				// so things can settle
				svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
			}
			else if(svs.perf_acc_realtime > 5)
			{
				svs.perf_cpuload = 1 - svs.perf_acc_sleeptime / svs.perf_acc_realtime;
				svs.perf_lost = svs.perf_acc_lost / svs.perf_acc_realtime;
				if(svs.perf_acc_offset_samples > 0)
				{
					svs.perf_offset_max = svs.perf_acc_offset_max;
					svs.perf_offset_avg = svs.perf_acc_offset / svs.perf_acc_offset_samples;
					svs.perf_offset_sdev = sqrt(svs.perf_acc_offset_squared / svs.perf_acc_offset_samples - svs.perf_offset_avg * svs.perf_offset_avg);
				}
				if(svs.perf_lost > 0 && developer_extra.integer)
					if(playing) // only complain if anyone is looking
						Con_DPrintf("Server can't keep up: %s\n", Host_TimingReport(vabuf, sizeof(vabuf)));
				svs.perf_acc_realtime = svs.perf_acc_sleeptime = svs.perf_acc_lost = svs.perf_acc_offset = svs.perf_acc_offset_squared = svs.perf_acc_offset_max = svs.perf_acc_offset_samples = 0;
			}
		}

		if (slowmo.value < 0.00001 && slowmo.value != 0)
			Cvar_SetValue("slowmo", 0);
		if (host_framerate.value < 0.00001 && host_framerate.value != 0)
			Cvar_SetValue("host_framerate", 0);

		// keep the random time dependent, but not when playing demos/benchmarking
		if(!*sv_random_seed.string && !cls.demoplayback)
			rand();

		// get new key events
		Key_EventQueue_Unblock();
		SndSys_SendKeyEvents();
		Sys_SendKeyEvents();

		NetConn_UpdateSockets();

		Log_DestBuffer_Flush();

		// receive packets on each main loop iteration, as the main loop may
		// be undersleeping due to select() detecting a new packet
		if (sv.active && !svs.threaded)
			NetConn_ServerFrame();

		Curl_Run();

		// check for commands typed to the host
		Host_GetConsoleCommands();

		// when a server is running we only execute console commands on server frames
		// (this mainly allows frikbot .way config files to work properly by staying in sync with the server qc)
		// otherwise we execute them on client frames
		if (sv.active ? sv_timer > 0 : cl_timer > 0)
		{
			// process console commands
//			R_TimeReport("preconsole");
			CL_VM_PreventInformationLeaks();
			Cbuf_Frame();
//			R_TimeReport("console");
		}

		//Con_Printf("%6.0f %6.0f\n", cl_timer * 1000000.0, sv_timer * 1000000.0);

		// if the accumulators haven't become positive yet, wait a while
		if (cls.state == ca_dedicated)
			wait = sv_timer * -1000000.0;
		else if (!sv.active || svs.threaded)
			wait = cl_timer * -1000000.0;
		else
			wait = max(cl_timer, sv_timer) * -1000000.0;

		if (!cls.timedemo && wait >= 1)
		{
			double time0, delta;

			if(host_maxwait.value <= 0)
				wait = min(wait, 1000000.0);
			else
				wait = min(wait, host_maxwait.value * 1000.0);
			if(wait < 1)
				wait = 1; // because we cast to int

			time0 = Sys_DirtyTime();
			if (sv_checkforpacketsduringsleep.integer && !sys_usenoclockbutbenchmark.integer && !svs.threaded)
				NetConn_SleepMicroseconds((int)wait);
			else
				Sys_Sleep((int)wait);
			delta = Sys_DirtyTime() - time0;
			if (delta < 0 || delta >= 1800) delta = 0;
			if (!svs.threaded)
				svs.perf_acc_sleeptime += delta;
//			R_TimeReport("sleep");
			continue;
		}

		// limit the frametime steps to no more than 100ms each
		if (cl_timer > 0.1)
			cl_timer = 0.1;
		if (sv_timer > 0.1)
		{
			if (!svs.threaded)
				svs.perf_acc_lost += (sv_timer - 0.1);
			sv_timer = 0.1;
		}

		R_TimeReport("---");

	//-------------------
	//
	// server operations
	//
	//-------------------

		// limit the frametime steps to no more than 100ms each
		if (sv.active && sv_timer > 0 && !svs.threaded)
		{
			// execute one or more server frames, with an upper limit on how much
			// execution time to spend on server frames to avoid freezing the game if
			// the server is overloaded, this execution time limit means the game will
			// slow down if the server is taking too long.
			int framecount, framelimit = 1;
			double advancetime, aborttime = 0;
			float offset;
			prvm_prog_t *prog = SVVM_prog;

			// run the world state
			// don't allow simulation to run too fast or too slow or logic glitches can occur

			// stop running server frames if the wall time reaches this value
			if (sys_ticrate.value <= 0)
				advancetime = sv_timer;
			else if (cl.islocalgame && !sv_fixedframeratesingleplayer.integer)
			{
				// synchronize to the client frametime, but no less than 10ms and no more than 100ms
				advancetime = bound(0.01, cl_timer, 0.1);
			}
			else
			{
				advancetime = sys_ticrate.value;
				// listen servers can run multiple server frames per client frame
				framelimit = cl_maxphysicsframesperserverframe.integer;
				aborttime = Sys_DirtyTime() + 0.1;
			}
			if(slowmo.value > 0 && slowmo.value < 1)
				advancetime = min(advancetime, 0.1 / slowmo.value);
			else
				advancetime = min(advancetime, 0.1);

			if(advancetime > 0)
			{
				offset = Sys_DirtyTime() - dirtytime;if (offset < 0 || offset >= 1800) offset = 0;
				offset += sv_timer;
				++svs.perf_acc_offset_samples;
				svs.perf_acc_offset += offset;
				svs.perf_acc_offset_squared += offset * offset;
				if(svs.perf_acc_offset_max < offset)
					svs.perf_acc_offset_max = offset;
			}

			// only advance time if not paused
			// the game also pauses in singleplayer when menu or console is used
			sv.frametime = advancetime * slowmo.value;
			if (host_framerate.value)
				sv.frametime = host_framerate.value;
			if (sv.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
				sv.frametime = 0;

			for (framecount = 0;framecount < framelimit && sv_timer > 0;framecount++)
			{
				sv_timer -= advancetime;

				// move things around and think unless paused
				if (sv.frametime)
					SV_Physics();

				// if this server frame took too long, break out of the loop
				if (framelimit > 1 && Sys_DirtyTime() >= aborttime)
					break;
			}
			R_TimeReport("serverphysics");

			// send all messages to the clients
			SV_SendClientMessages();

			if (sv.paused == 1 && realtime > sv.pausedstart && sv.pausedstart > 0) {
				prog->globals.generic[OFS_PARM0] = realtime - sv.pausedstart;
				PRVM_serverglobalfloat(time) = sv.time;
				prog->ExecuteProgram(prog, PRVM_serverfunction(SV_PausedTic), "QC function SV_PausedTic is missing");
			}

			// send an heartbeat if enough time has passed since the last one
			NetConn_Heartbeat(0);
			R_TimeReport("servernetwork");
		}
		else if (!svs.threaded)
		{
			// don't let r_speeds display jump around
			R_TimeReport("serverphysics");
			R_TimeReport("servernetwork");
		}

	//-------------------
	//
	// client operations
	//
	//-------------------

		if (cls.state != ca_dedicated && (cl_timer > 0 || cls.timedemo || ((vid_activewindow ? cl_maxfps : cl_maxidlefps).value < 1)))
		{
			R_TimeReport("---");
			Collision_Cache_NewFrame();
			R_TimeReport("collisioncache");
			// decide the simulation time
			if (cls.capturevideo.active)
			{
				//***
				if (cls.capturevideo.realtime)
					clframetime = cl.realframetime = max(cl_timer, 1.0 / cls.capturevideo.framerate);
				else
				{
					clframetime = 1.0 / cls.capturevideo.framerate;
					cl.realframetime = max(cl_timer, clframetime);
				}
			}
			else if (vid_activewindow && cl_maxfps.value >= 1 && !cls.timedemo)
			{
				clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxfps.value);
				// when running slow, we need to sleep to keep input responsive
				wait = bound(0, cl_maxfps_alwayssleep.value * 1000, 100000);
				if (wait > 0)
					Sys_Sleep((int)wait);
			}
			else if (!vid_activewindow && cl_maxidlefps.value >= 1 && !cls.timedemo)
				clframetime = cl.realframetime = max(cl_timer, 1.0 / cl_maxidlefps.value);
			else
				clframetime = cl.realframetime = cl_timer;

			// apply slowmo scaling
			clframetime *= cl.movevars_timescale;
			// scale playback speed of demos by slowmo cvar
			if (cls.demoplayback)
			{
				clframetime *= slowmo.value;
				// if demo playback is paused, don't advance time at all
				if (cls.demopaused)
					clframetime = 0;
			}

			// host_framerate overrides all else
			if (host_framerate.value)
				clframetime = host_framerate.value;

			if (cl.paused || (cl.islocalgame && (key_dest != key_game || key_consoleactive || cl.csqc_paused)))
				clframetime = 0;

			if (cls.timedemo)
				clframetime = cl.realframetime = cl_timer;

			// deduct the frame time from the accumulator
			cl_timer -= cl.realframetime;

			cl.oldtime = cl.time;
			cl.time += clframetime;

			// update video
			if (host_speeds.integer)
				time1 = Sys_DirtyTime();
			R_TimeReport("pre-input");

			// Collect input into cmd
			CL_Input();

			R_TimeReport("input");

			// check for new packets
			NetConn_ClientFrame();

			// read a new frame from a demo if needed
			CL_ReadDemoMessage();
			R_TimeReport("clientnetwork");

			// now that packets have been read, send input to server
			CL_SendMove();
			R_TimeReport("sendmove");

			// update client world (interpolate entities, create trails, etc)
			CL_UpdateWorld();
			R_TimeReport("lerpworld");

			CL_Video_Frame();

			R_TimeReport("client");

			CL_UpdateScreen();
			R_TimeReport("render");

			if (host_speeds.integer)
				time2 = Sys_DirtyTime();

			// update audio
			if(cl.csqc_usecsqclistener)
			{
				S_Update(&cl.csqc_listenermatrix);
				cl.csqc_usecsqclistener = false;
			}
			else
				S_Update(&r_refdef.view.matrix);

			CDAudio_Update();
			R_TimeReport("audio");

			// reset gathering of mouse input
			in_mouse_x = in_mouse_y = 0;

			if (host_speeds.integer)
			{
				pass1 = (int)((time1 - time3)*1000000);
				time3 = Sys_DirtyTime();
				pass2 = (int)((time2 - time1)*1000000);
				pass3 = (int)((time3 - time2)*1000000);
				Con_Printf("%6ius total %6ius server %6ius gfx %6ius snd\n",
							pass1+pass2+pass3, pass1, pass2, pass3);
			}
		}

#if MEMPARANOIA
		Mem_CheckSentinelsGlobal();
#else
		if (developer_memorydebug.integer)
			Mem_CheckSentinelsGlobal();
#endif

		// if there is some time remaining from this frame, reset the timers
		if (cl_timer >= 0)
			cl_timer = 0;
		if (sv_timer >= 0)
		{
			if (!svs.threaded)
				svs.perf_acc_lost += sv_timer;
			sv_timer = 0;
		}

		host_framecount++;
	}
}
Ejemplo n.º 18
0
lhnetsocket_t *LHNET_OpenSocket_Connectionless(lhnetaddress_t *address)
{
	lhnetsocket_t *lhnetsocket, *s;
	if (!address)
		return NULL;
	lhnetsocket = (lhnetsocket_t *)Z_Malloc(sizeof(*lhnetsocket));
	if (lhnetsocket)
	{
		memset(lhnetsocket, 0, sizeof(*lhnetsocket));
		lhnetsocket->address = *address;
		switch(lhnetsocket->address.addresstype)
		{
		case LHNETADDRESSTYPE_LOOP:
			if (lhnetsocket->address.port == 0)
			{
				// allocate a port dynamically
				// this search will always terminate because there is never
				// an allocated socket with port 0, so if the number wraps it
				// will find the port is unused, and then refuse to use port
				// 0, causing an intentional failure condition
				lhnetsocket->address.port = 1024;
				for (;;)
				{
					for (s = lhnet_socketlist.next;s != &lhnet_socketlist;s = s->next)
						if (s->address.addresstype == lhnetsocket->address.addresstype && s->address.port == lhnetsocket->address.port)
							break;
					if (s == &lhnet_socketlist)
						break;
					lhnetsocket->address.port++;
				}
			}
			// check if the port is available
			for (s = lhnet_socketlist.next;s != &lhnet_socketlist;s = s->next)
				if (s->address.addresstype == lhnetsocket->address.addresstype && s->address.port == lhnetsocket->address.port)
					break;
			if (s == &lhnet_socketlist && lhnetsocket->address.port != 0)
			{
				lhnetsocket->next = &lhnet_socketlist;
				lhnetsocket->prev = lhnetsocket->next->prev;
				lhnetsocket->next->prev = lhnetsocket;
				lhnetsocket->prev->next = lhnetsocket;
				return lhnetsocket;
			}
			break;
		case LHNETADDRESSTYPE_INET4:
#ifndef NOSUPPORTIPV6
		case LHNETADDRESSTYPE_INET6:
#endif
#ifdef WIN32
			if (lhnet_didWSAStartup)
			{
#endif
#ifndef NOSUPPORTIPV6
				if ((lhnetsocket->inetsocket = socket(address->addresstype == LHNETADDRESSTYPE_INET6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1)
#else
				if ((lhnetsocket->inetsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1)
#endif
				{
#ifdef WIN32
					u_long _false = 0;
#endif
#ifdef MSG_DONTWAIT
					if (1)
#else
#ifdef WIN32
					u_long _true = 1;
#else
					char _true = 1;
#endif
					if (ioctlsocket(lhnetsocket->inetsocket, FIONBIO, &_true) != -1)
#endif
					{
#ifdef IPV6_V6ONLY
						// We need to set this flag to tell the OS that we only listen on IPv6. If we don't
						// most OSes will create a dual-protocol socket that also listens on IPv4. In this case
						// if an IPv4 socket is already bound to the port we want, our bind() call will fail.
						int ipv6_only = 1;
						if (address->addresstype != LHNETADDRESSTYPE_INET6
							|| setsockopt (lhnetsocket->inetsocket, IPPROTO_IPV6, IPV6_V6ONLY,
										   (const char *)&ipv6_only, sizeof(ipv6_only)) == 0
#ifdef WIN32
							// The Win32 API only supports IPV6_V6ONLY since Windows Vista, but fortunately
							// the default value is what we want on Win32 anyway (IPV6_V6ONLY = true)
							|| SOCKETERRNO == WSAENOPROTOOPT
#endif
							)
#endif
						{
							lhnetaddressnative_t *localaddress = (lhnetaddressnative_t *)&lhnetsocket->address;
							SOCKLEN_T namelen;
							int bindresult;

#if defined(SOL_RFC1149) && defined(RFC1149_1149ONLY)
							// we got reports of massive lags when this protocol was chosen as transport
							// so better turn it off
							{
								int rfc1149only = 0;
								int rfc1149enabled = 0;
								if(setsockopt(lhnetsocket->inetsocket, SOL_RFC1149, RFC1149_1149ONLY, &rfc1149only))
									Con_Printf("LHNET_OpenSocket_Connectionless: warning: setsockopt(RFC1149_1149ONLY) returned error: %s\n", LHNETPRIVATE_StrError());
								if(setsockopt(lhnetsocket->inetsocket, SOL_RFC1149, RFC1149_ENABLED, &rfc1149enabled))
									Con_Printf("LHNET_OpenSocket_Connectionless: warning: setsockopt(RFC1149_ENABLED) returned error: %s\n", LHNETPRIVATE_StrError());
							}
#endif

#ifndef NOSUPPORTIPV6
							if (address->addresstype == LHNETADDRESSTYPE_INET6)
							{
								namelen = sizeof(localaddress->addr.in6);
								bindresult = bind(lhnetsocket->inetsocket, &localaddress->addr.sock, namelen);
								if (bindresult != -1)
								{
									if (getsockname(lhnetsocket->inetsocket, &localaddress->addr.sock, &namelen))
									{
										// If getsockname failed, we can assume the bound socket is useless.
										bindresult = -1;
									}
								}
							}
							else
#endif
							{
								namelen = sizeof(localaddress->addr.in);
								bindresult = bind(lhnetsocket->inetsocket, &localaddress->addr.sock, namelen);
								if (bindresult != -1)
								{
									if (getsockname(lhnetsocket->inetsocket, &localaddress->addr.sock, &namelen))
									{
										// If getsockname failed, we can assume the bound socket is useless.
										bindresult = -1;
									}
								}
							}
							if (bindresult != -1)
							{
								int i = 1;
								// enable broadcast on this socket
								setsockopt(lhnetsocket->inetsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i));
#ifdef IP_TOS
								{
									// enable DSCP for ToS support
									int tos = lhnet_default_dscp << 2;
									if (setsockopt(lhnetsocket->inetsocket, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)))
									{
										// Error in setsockopt - fine, we'll simply set no TOS then.
									}
								}
#endif
								lhnetsocket->next = &lhnet_socketlist;
								lhnetsocket->prev = lhnetsocket->next->prev;
								lhnetsocket->next->prev = lhnetsocket;
								lhnetsocket->prev->next = lhnetsocket;
#ifdef WIN32
								if (ioctlsocket(lhnetsocket->inetsocket, SIO_UDP_CONNRESET, &_false) == -1)
									Con_DPrintf("LHNET_OpenSocket_Connectionless: ioctlsocket SIO_UDP_CONNRESET returned error: %s\n", LHNETPRIVATE_StrError());
#endif
								return lhnetsocket;
							}
							else
								Con_Printf("LHNET_OpenSocket_Connectionless: bind returned error: %s\n", LHNETPRIVATE_StrError());
						}
#ifdef IPV6_V6ONLY
						else
							Con_Printf("LHNET_OpenSocket_Connectionless: setsockopt(IPV6_V6ONLY) returned error: %s\n", LHNETPRIVATE_StrError());
#endif
					}
					else
						Con_Printf("LHNET_OpenSocket_Connectionless: ioctlsocket returned error: %s\n", LHNETPRIVATE_StrError());
					closesocket(lhnetsocket->inetsocket);
				}
				else
					Con_Printf("LHNET_OpenSocket_Connectionless: socket returned error: %s\n", LHNETPRIVATE_StrError());
#ifdef WIN32
			}
			else
				Con_Print("LHNET_OpenSocket_Connectionless: can't open a socket (WSAStartup failed during LHNET_Init)\n");
#endif
			break;
		default:
			break;
		}
		Z_Free(lhnetsocket);
	}
	return NULL;
}
Ejemplo n.º 19
0
qbool NET_GetTCPPacket_SV (netsrc_t netsrc, netadr_t *from, sizebuf_t *message)
{
	int ret;
	float timeval = Sys_DoubleTime();
	svtcpstream_t *st = NULL, *next = NULL;

	if (netsrc != NS_SERVER)
		return false;

	for (st = svs.tcpstreams; st; st = next)
	{
		next = st->next;

		*from = st->remoteaddr;

		if (st->socketnum == INVALID_SOCKET || st->drop)
		{
			sv_tcp_connection_free(st, true); // free and unlink
			continue;
		}

		//due to the above checks about invalid sockets, the socket is always open for st below.

		// check for client timeout
		if (st->timeouttime < timeval)
		{
			st->drop = true;
			continue;
		}

		ret = recv(st->socketnum, st->inbuffer+st->inlen, sizeof(st->inbuffer)-st->inlen, 0);
		if (ret == 0)
		{
			// connection closed
			st->drop = true;
			continue;
		}
		else if (ret == -1)
		{
			int err = qerrno;

			if (err == EWOULDBLOCK)
			{
				ret = 0; // it's OK
			}
			else
			{
				if (err == ECONNABORTED || err == ECONNRESET)
				{
					Con_DPrintf ("Connection lost or aborted\n"); //server died/connection lost.
				}
				else
				{
					Con_DPrintf ("NET_GetPacket: Error (%i): %s\n", err, strerror(err));
				}

				st->drop = true;
				continue;
			}
		}
		else
		{
			// update timeout
			st->timeouttime = Sys_DoubleTime() + 10;
		}

		st->inlen += ret;

		if (st->waitingforprotocolconfirmation)
		{
			// not enough data
			if (st->inlen < 6)
				continue;

			if (strncmp(st->inbuffer, "qizmo\n", 6))
			{
				Con_Printf ("Unknown TCP client\n");
				st->drop = true;
				continue;
			}

			// remove leading 6 bytes
			memmove(st->inbuffer, st->inbuffer+6, st->inlen - (6));
			st->inlen -= 6;
			// confirmed
			st->waitingforprotocolconfirmation = false;
		}

		// need two bytes for packet len
		if (st->inlen < 2)
			continue;

		message->cursize = BigShort(*(short*)st->inbuffer);
		if (message->cursize < 0)
		{
			message->cursize = 0;
			Con_Printf ("Warning: malformed message from %s\n", NET_AdrToString (*from));
			st->drop = true;
			continue;
		}

		if (message->cursize >= message->maxsize)
		{
			Con_Printf ("Warning: Oversize packet from %s\n", NET_AdrToString (*from));
			st->drop = true;
			continue;
		}

		if (message->cursize + 2 > st->inlen)
		{
			//not enough buffered to read a packet out of it.
			continue;
		}

		memcpy(message->data, st->inbuffer + 2, message->cursize);
		memmove(st->inbuffer, st->inbuffer + message->cursize + 2, st->inlen - (message->cursize + 2));
		st->inlen -= message->cursize + 2;

		return true; // we got packet!
	}

	return false; // no packet received.
}
Ejemplo n.º 20
0
/*
===================
SV_ReadClientMessage

Returns false if the client should be killed
===================
*/
qboolean SV_ReadClientMessage (void)
{
	int		ret;
	int		cmd;
	char		*s;
	
	do
	{
nextmsg:
		ret = NET_GetMessage (host_client->netconnection);
		if (ret == -1)
		{
			Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n");
			return false;
		}
		if (!ret)
			return true;
					
		MSG_BeginReading ();
		
		while (1)
		{
			if (!host_client->active)
				return false;	// a command caused an error

			if (msg_badread)
			{
				Sys_Printf ("SV_ReadClientMessage: badread\n");
				return false;
			}	
	
			cmd = MSG_ReadChar ();
			
			switch (cmd)
			{
			case -1:
				goto nextmsg;		// end of message
				
			default:
				Sys_Printf ("SV_ReadClientMessage: unknown command char\n");
				return false;
							
			case clc_nop:
//				Sys_Printf ("clc_nop\n");
				break;
				
			case clc_stringcmd:	
				s = MSG_ReadString ();
				if (host_client->privileged)
					ret = 2;
				else
					ret = 0;
				if (Q_strncasecmp(s, "status", 6) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "god", 3) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "notarget", 8) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "fly", 3) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "name", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "noclip", 6) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "say", 3) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "say_team", 8) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "tell", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "color", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "kill", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "pause", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "spawn", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "begin", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "prespawn", 8) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "kick", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "ping", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "give", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "ban", 3) == 0)
					ret = 1;
				if (ret == 2)
					Cbuf_InsertText (s);
				else if (ret == 1)
					Cmd_ExecuteString (s, src_client);
				else
					Con_DPrintf("%s tried to %s\n", host_client->name, s);
				break;
				
			case clc_disconnect:
//				Sys_Printf ("SV_ReadClientMessage: client disconnected\n");
				return false;
			
			case clc_move:
				SV_ReadClientMove (&host_client->cmd);
				break;
			}
		}
	} while (ret == 1);
	
	return true;
}
Ejemplo n.º 21
0
void CDAudio_Play(byte track, qboolean looping)
{
	struct cdrom_tocentry entry;
	struct cdrom_ti ti;

	if (cdfile == -1 || !enabled)
		return;
	
	if (!cdValid)
	{
		CDAudio_GetAudioDiskInfo();
		if (!cdValid)
			return;
	}

	track = remap[track];

	if (track < 1 || track > maxTrack)
	{
		Con_DPrintf("CDAudio: Bad track number %u.\n", track);
		return;
	}

	// don't try to play a non-audio track
	entry.cdte_track = track;
	entry.cdte_format = CDROM_MSF;
    if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 )
	{
		Con_DPrintf("ioctl cdromreadtocentry failed\n");
		return;
	}
	if (entry.cdte_ctrl == CDROM_DATA_TRACK)
	{
		Con_Printf("CDAudio: track %i is not audio\n", track);
		return;
	}

	if (playing)
	{
		if (playTrack == track)
			return;
		CDAudio_Stop();
	}

	ti.cdti_trk0 = track;
	ti.cdti_trk1 = track;
	ti.cdti_ind0 = 1;
	ti.cdti_ind1 = 99;

	if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 ) 
    {
		Con_DPrintf("ioctl cdromplaytrkind failed\n");
		return;
    }

	if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
		Con_DPrintf("ioctl cdromresume failed\n");

	playLooping = looping;
	playTrack = track;
	playing = true;

	if (cdvolume == 0.0)
		CDAudio_Pause ();
}
Ejemplo n.º 22
0
int CDAudio_Play(byte track, qboolean looping)
{
    DWORD				dwReturn;
    MCI_PLAY_PARMS		mciPlayParms;
    MCI_STATUS_PARMS	mciStatusParms;

    if (!cd_enabled.value || !initialized) // Manoel Kasimier - CD player in menu - edited
        return 0;

    if (!cdValid)
    {
        CDAudio_GetAudioDiskInfo();
        if (!cdValid)
            return 0;
    }

    track = remap[track];


    if (track < 1 || track > maxTrack)
    {
        Con_DPrintf("CDAudio: Bad track number %u.\n", track);
        return 0;
    }

    // don't try to play a non-audio track
    mciStatusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
    mciStatusParms.dwTrack = track;
    dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
    if (dwReturn)
    {
        Con_DPrintf("MCI_STATUS failed (%i)\n", dwReturn);
        return 0;
    }
    if (mciStatusParms.dwReturn != MCI_CDA_TRACK_AUDIO)
    {
        Con_Printf("CDAudio: track %i is not audio\n", track);
        return 0;
    }

    // get the length of the track to be played
    mciStatusParms.dwItem = MCI_STATUS_LENGTH;
    mciStatusParms.dwTrack = track;
    dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
    if (dwReturn)
    {
        Con_DPrintf("MCI_STATUS failed (%i)\n", dwReturn);
        return 0;
    }

    if (playing)
    {
        if (playTrack == track)
            return 1;
        CDAudio_Stop();
    }

    mciPlayParms.dwFrom = MCI_MAKE_TMSF(track, 0, 0, 0);
    mciPlayParms.dwTo = (mciStatusParms.dwReturn << 8) | track;
    mciPlayParms.dwCallback = (DWORD)mainwindow;
    dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD)(LPVOID) &mciPlayParms);
    if (dwReturn)
    {
        Con_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn);
        return 0;
    }

    playLooping = looping;
    playTrack = track;
    playing = true;

    if (cdvolume == 0.0)
        CDAudio_Pause ();
        return 1;
}
Ejemplo n.º 23
0
/*
=================
Mod_LoadLighting
=================
*/
void Mod_LoadLighting (lump_t *l)
{
// 2001-09-11 Colored lightning by LordHavoc/Sarcazm/Maddes  start
/*
	if (!l->filelen)
	{
		loadmodel->lightdata = NULL;
		return;
	}
	loadmodel->lightdata = Hunk_AllocName ( l->filelen, loadname);
	memcpy (loadmodel->lightdata, mod_base + l->fileofs, l->filelen);
*/
	int		i;
	byte	*in, *out, *data;
	byte	d;
	char	litfilename[1024];
	loadedfile_t	*fileinfo;	// 2001-09-12 Returning information about loaded file by Maddes

	loadmodel->lightdata = NULL;

	if (external_lit->value)
	{
		// check for a .LIT file
		strcpy(litfilename, loadmodel->name);
		COM_StripExtension(litfilename, litfilename);
		strcat(litfilename, ".lit");

// 2001-09-12 Returning information about loaded file by Maddes  start
/*
		data = (byte*) COM_LoadHunkFile(litfilename);
		if (data)
*/
		fileinfo = COM_LoadHunkFile(litfilename);
		if (fileinfo)
// 2001-09-12 Returning information about loaded file by Maddes  end
		{
			Con_DPrintf("%s loaded from %s\n", litfilename, fileinfo->path->pack ? fileinfo->path->pack->filename : fileinfo->path->filename);	// 2001-09-12 Displaying where .LIT file is loaded from by Maddes
			data = fileinfo->data;	// 2001-09-12 Returning information about loaded file by Maddes
			if (data[0] == 'Q' && data[1] == 'L' && data[2] == 'I' && data[3] == 'T')
			{
				i = LittleLong(((int *)data)[1]);
				if (i == 1)
				{
					loadmodel->lightdata = data + 8;
					return;
				}
				else
					Con_Printf("Unknown .LIT file version (%d)\n", i);
			}
			else
				Con_Printf("Corrupt .LIT file (old version?), ignoring\n");
		}

		// no .LIT found, expand the white lighting data to color
	}

	if (!l->filelen)
		return;
	loadmodel->lightdata = Hunk_AllocName ( l->filelen*3, loadname);
	in = loadmodel->lightdata + l->filelen*2; // place the file at the end, so it will not be overwritten until the very last write
	out = loadmodel->lightdata;
	memcpy (in, mod_base + l->fileofs, l->filelen);
	for (i = 0;i < l->filelen;i++)
	{
		d = *in++;
		*out++ = d;
		*out++ = d;
		*out++ = d;
	}
// 2001-09-11 Colored lightning by LordHavoc/Sarcazm/Maddes  end
}
Ejemplo n.º 24
0
int CDAudio_Init(void)
{
    DWORD	dwReturn;
    MCI_OPEN_PARMS	mciOpenParms;
    MCI_SET_PARMS	mciSetParms;
    int				n;

    static qboolean cd_initialized; // Manoel Kasimier - Windows XP fix
    // Manoel Kasimier - CD player in menu - begin
    cdValid = false;
    playing = false;
    wasPlaying = false;
    playLooping = false;
    // Manoel Kasimier - CD player in menu - end

    if (cls.state == ca_dedicated)
        return -1;

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

    mciOpenParms.lpstrDeviceType = "cdaudio";
    if (dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE, (DWORD) (LPVOID) &mciOpenParms))
    {
        Con_Printf("CDAudio_Init: MCI_OPEN failed (%i)\n", dwReturn);
        return -1;
    }
    wDeviceID = mciOpenParms.wDeviceID;

    // Set the time format to track/minute/second/frame (TMSF).
    mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
    if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &mciSetParms))
    {
        Con_Printf("MCI_SET_TIME_FORMAT failed (%i)\n", dwReturn);
        mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD)NULL);
        return -1;
    }

    for (n = 0; n < 100; n++)
        remap[n] = n;
    initialized = true;

    if (CDAudio_GetAudioDiskInfo())
    {
        Con_DPrintf("CDAudio_Init: No CD in player.\n"); // edited
        cdValid = false;
    }
    // Manoel Kasimier - Windows XP fix - begin
    if (!cd_initialized)
    {
        cd_initialized = true;
        Cvar_RegisterVariableWithCallback(&cd_enabled, cd_cvar_check);
        // Manoel Kasimier - Windows XP fix - end
        Cmd_AddCommand ("cd", CD_f);
        CD_FindCDAux(); // Hexen 2
    } // Manoel Kasimier - Windows XP fix

    Con_DPrintf("CD Audio Initialized\n"); // edited

    return 0;
}
Ejemplo n.º 25
0
/*
=================
Mod_LoadQ3Model
=================
*/
void Mod_LoadQ3Model (model_t *mod, const void *buffer)
{
	md3header_t		*header;
	md3surface_t	*surf;
	int				 i, j, picmip_flag;
	md3shader_t		*shader;
	md3frame_t		*frame;
//	md3ver_t		*vert;
	byte			*modeldata;
	const char		**pathlist;
	const char		*namelist[2];
	char			path[MAX_OSPATH];

	header = (md3header_t *) buffer;
	if (header->version != 15)
	{
		Con_Printf ("\x02""ERROR: incorrect version of MD3 file %s\n", mod->name);
		return;
	}

	Con_DPrintf ("Loading md3 model...%s (%s)\n", header->filename, mod->name);

	frame = (md3frame_t *) ((byte *) header + header->frame_offs);
	for (i = 0; i < header->num_frames; i++, frame++)
	{
		VectorCopy (frame->pos, md3bboxmins);
		VectorCopy (frame->pos, md3bboxmaxs);

		for (j = 0; j < 3; j++)
		{
			if (frame->mins[j] < md3bboxmins[j])
				md3bboxmins[j] = frame->mins[j];
			if (frame->maxs[j] > md3bboxmaxs[j])
				md3bboxmaxs[j] = frame->maxs[j];
		}

	}

#ifndef RQM_SV_ONLY
	picmip_flag = gl_picmip_all.value ? TEX_MIPMAP : 0;
#else
	picmip_flag = 0;
#endif

	surf = (md3surface_t *) ((byte *)header + header->surface_offs);
	for (i=0; i < header->num_surfaces; i++)
	{
		if (*(long *)surf->id != MD3IDHEADER)
		{
			Con_Printf ("\x02""MD3 bad surface for: %s\n", header->filename);
			break;
		}

		/*vert = (md3vert_t *) ((byte *) surf + surf->vert_offs);
		for (j=0; j < surf->num_surf_verts * surf->num_surf_frames; j++, vert++)
		{
			float lat;
			float lng;

			//convert verts from shorts to floats
			md3vert_mem_t   *mem_vert = (md3vert_mem_t *)((byte *)mem_head + posn);
			md3vert_t      *disk_vert = (md3vert_t *)((byte *)surf + surf->vert_offs + j * sizeof(md3vert_t));

			mem_vert->vec[0] = (float)disk_vert->vec[0] / 64.0f;
			mem_vert->vec[1] = (float)disk_vert->vec[1] / 64.0f;
			mem_vert->vec[2] = (float)disk_vert->vec[2] / 64.0f;

			//work out normals
			lat = (disk_vert->normal + 255) * (2 * 3.141592654) / 255;
			lng = ((disk_vert->normal >> 8) & 255) * (2 * 3.141592654) / 255;

			mem_vert->normal[0] = cos (lat) * sin (lng);
			mem_vert->normal[1] = sin (lat) * sin (lng);
			mem_vert->normal[2] = cos (lng);
		} */

		// load all the external textures:
		shader = (md3shader_t *)((byte *)surf + surf->shader_offs);
		for (j=0; j < surf->num_surf_shaders; j++, shader++)
		{
		#ifndef RQM_SV_ONLY
			//shader->index = GL_LoadTextureImage ("", shader->name, NULL, picmip_flag | TEX_BLEND, mod_loadpath->dir_level);
			namelist[0] = COM_SkipPath (shader->name);
			namelist[1] = NULL;
			if (namelist[0] != shader->name)
			{
				Q_strncpy (path, sizeof(path), shader->name, namelist[0]-shader->name);
				md3_paths[0] = path;
				pathlist = &md3_paths[0];
			}
			else
			{
				pathlist = &md3_paths[1];		// no custom path
			}

			shader->index = GL_LoadTextureImage_MultiSource (pathlist, namelist, NULL, picmip_flag | TEX_BLEND, mod_loadpath->dir_level);
			if (!shader->index)
			{
				Con_Printf ("\x02""Model: %s  Texture missing: %s\n", mod->name, shader->name);
			}
		#else
			shader->index = 0;
		#endif
		}

		surf = (md3surface_t *)((byte *)surf + surf->end_offs);
	}

	modeldata = Cache_Alloc (&mod->cache, header->end_offs, mod->name);
	if (!modeldata)
	{
		Con_DPrintf ("\x02""cache alloc failed...%s (%s)\n", header->filename, mod->name);
		return;   //cache alloc failed
	}

	memcpy (modeldata, buffer, header->end_offs);

	mod->type = mod_md3;
//	mod->aliastype = MD3IDHEADER;
	mod->numframes = header->num_frames;

	mod->modhint = Mod_GetAliasHint (mod->name);
	mod->flags = header->flags;

	if (mod->modhint == MOD_HEAD)
		mod->flags |= EF_GIB;
	else
		mod->flags |= Mod_GetQ3ModelFlags (mod->name);

	VectorScale (md3bboxmaxs, 1.0/64.0, mod->maxs);
	VectorScale (md3bboxmins, 1.0/64.0, mod->mins);
}
Ejemplo n.º 26
0
/*
====================
CheckPendingDownloads

checks if there are free download slots to start new downloads in.
To not start too many downloads at once, only one download is added at a time,
up to a maximum number of cl_curl_maxdownloads are running.
====================
*/
static void CheckPendingDownloads(void)
{
	const char *h;
	char urlbuf[1024];
	char vabuf[1024];
	if(!curl_dll)
		return;
	if(numdownloads < cl_curl_maxdownloads.integer)
	{
		downloadinfo *di;
		for(di = downloads; di; di = di->next)
		{
			if(!di->started)
			{
				if(!di->buffer)
				{
					Con_Printf("Downloading %s -> %s", CleanURL(di->url, urlbuf, sizeof(urlbuf)), di->filename);

					di->stream = FS_OpenRealFile(di->filename, "ab", false);
					if(!di->stream)
					{
						Con_Printf("\nFAILED: Could not open output file %s\n", di->filename);
						Curl_EndDownload(di, CURL_DOWNLOAD_FAILED, CURLE_OK, NULL);
						return;
					}
					FS_Seek(di->stream, 0, SEEK_END);
					di->startpos = FS_Tell(di->stream);

					if(di->startpos > 0)
						Con_Printf(", resuming from position %ld", (long) di->startpos);
					Con_Print("...\n");
				}
				else
				{
					Con_DPrintf("Downloading %s -> memory\n", CleanURL(di->url, urlbuf, sizeof(urlbuf)));
					di->startpos = 0;
				}

				di->curle = qcurl_easy_init();
				di->slist = NULL;
				qcurl_easy_setopt(di->curle, CURLOPT_URL, di->url);
				if(cl_curl_useragent.integer)
				{
					const char *ua
#ifdef HTTP_USER_AGENT
						= HTTP_USER_AGENT;
#else
						= engineversion;
#endif
					if(!ua)
						ua = "";
					if(*cl_curl_useragent_append.string)
						ua = va(vabuf, sizeof(vabuf), "%s%s%s",
							ua,
							(ua[0] && ua[strlen(ua)-1] != ' ')
								? " "
								: "",
							cl_curl_useragent_append.string);
					qcurl_easy_setopt(di->curle, CURLOPT_USERAGENT, ua);
				}
				else
					qcurl_easy_setopt(di->curle, CURLOPT_USERAGENT, "");
				qcurl_easy_setopt(di->curle, CURLOPT_REFERER, di->referer);
				qcurl_easy_setopt(di->curle, CURLOPT_RESUME_FROM, (long) di->startpos);
				qcurl_easy_setopt(di->curle, CURLOPT_FOLLOWLOCATION, 1);
				qcurl_easy_setopt(di->curle, CURLOPT_WRITEFUNCTION, CURL_fwrite);
				qcurl_easy_setopt(di->curle, CURLOPT_LOW_SPEED_LIMIT, (long) 256);
				qcurl_easy_setopt(di->curle, CURLOPT_LOW_SPEED_TIME, (long) 45);
				qcurl_easy_setopt(di->curle, CURLOPT_WRITEDATA, (void *) di);
				qcurl_easy_setopt(di->curle, CURLOPT_PRIVATE, (void *) di);
				qcurl_easy_setopt(di->curle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP);
				if(qcurl_easy_setopt(di->curle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP) != CURLE_OK)
				{
					Con_Printf("^1WARNING:^7 for security reasons, please upgrade to libcurl 7.19.4 or above. In a later version of DarkPlaces, HTTP redirect support will be disabled for this libcurl version.\n");
					//qcurl_easy_setopt(di->curle, CURLOPT_FOLLOWLOCATION, 0);
				}
				if(di->post_content_type)
				{
					qcurl_easy_setopt(di->curle, CURLOPT_POST, 1);
					qcurl_easy_setopt(di->curle, CURLOPT_POSTFIELDS, di->postbuf);
					qcurl_easy_setopt(di->curle, CURLOPT_POSTFIELDSIZE, di->postbufsize);
					di->slist = qcurl_slist_append(di->slist, va(vabuf, sizeof(vabuf), "Content-Type: %s", di->post_content_type));
				}

				// parse extra headers into slist
				// \n separated list!
				h = di->extraheaders;
				while(h)
				{
					const char *hh = strchr(h, '\n');
					if(hh)
					{
						char *buf = (char *) Mem_Alloc(tempmempool, hh - h + 1);
						memcpy(buf, h, hh - h);
						buf[hh - h] = 0;
						di->slist = qcurl_slist_append(di->slist, buf);
						h = hh + 1;
					}
					else
					{
						di->slist = qcurl_slist_append(di->slist, h);
						h = NULL;
					}
				}

				qcurl_easy_setopt(di->curle, CURLOPT_HTTPHEADER, di->slist);
				
				qcurl_multi_add_handle(curlm, di->curle);
				di->started = true;
				++numdownloads;
				if(numdownloads >= cl_curl_maxdownloads.integer)
					break;
			}
Ejemplo n.º 27
0
/*
===============
PR_LoadProgs
===============
*/
void PR_LoadProgs (void)
{
	int		i;

// flush the non-C variable lookup cache
	for (i=0 ; i<GEFV_CACHESIZE ; i++)
		gefvCache[i].field[0] = 0;

	CRC_Init (&pr_crc);

	progs = (dprograms_t *)COM_LoadHunkFile ("progs.dat");
	if (!progs)
		Sys_Error ("PR_LoadProgs: couldn't load progs.dat");
	Con_DPrintf ("Programs occupy %iK.\n", com_filesize/1024);

	for (i=0 ; i<com_filesize ; i++)
		CRC_ProcessByte (&pr_crc, ((byte *)progs)[i]);

// byte swap the header
	for (i=0 ; i<sizeof(*progs)/4 ; i++)
		((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );		

	if (progs->version != PROG_VERSION)
		Sys_Error ("progs.dat has wrong version number (%i should be %i)", progs->version, PROG_VERSION);
	if (progs->crc != PROGHEADER_CRC)
		Sys_Error ("progs.dat system vars have been modified, progdefs.h is out of date");

	pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
	pr_strings = (char *)progs + progs->ofs_strings;
	pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs);
	pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs);
	pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements);

	pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
	pr_globals = (float *)pr_global_struct;
	
	pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t);
	
// byte swap the lumps
	for (i=0 ; i<progs->numstatements ; i++)
	{
		pr_statements[i].op = LittleShort(pr_statements[i].op);
		pr_statements[i].a = LittleShort(pr_statements[i].a);
		pr_statements[i].b = LittleShort(pr_statements[i].b);
		pr_statements[i].c = LittleShort(pr_statements[i].c);
	}

	for (i=0 ; i<progs->numfunctions; i++)
	{
	pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement);
	pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start);
	pr_functions[i].s_name = LittleLong (pr_functions[i].s_name);
	pr_functions[i].s_file = LittleLong (pr_functions[i].s_file);
	pr_functions[i].numparms = LittleLong (pr_functions[i].numparms);
	pr_functions[i].locals = LittleLong (pr_functions[i].locals);
	}	

	for (i=0 ; i<progs->numglobaldefs ; i++)
	{
		pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type);
		pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs);
		pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name);
	}

	for (i=0 ; i<progs->numfielddefs ; i++)
	{
		pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type);
		if (pr_fielddefs[i].type & DEF_SAVEGLOBAL)
			Sys_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
		pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs);
		pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name);
	}

	for (i=0 ; i<progs->numglobals ; i++)
		((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]);
}
Ejemplo n.º 28
0
/*
====================
Host_Init
====================
*/
static void Host_Init (void)
{
	int i;
	const char* os;
	char vabuf[1024];

	if (COM_CheckParm("-profilegameonly"))
		Sys_AllowProfiling(false);

	// LordHavoc: quake never seeded the random number generator before... heh
	if (COM_CheckParm("-benchmark"))
		srand(0); // predictable random sequence for -benchmark
	else
		srand((unsigned int)time(NULL));

	// FIXME: this is evil, but possibly temporary
	// LordHavoc: doesn't seem very temporary...
	// LordHavoc: made this a saved cvar
// COMMANDLINEOPTION: Console: -developer enables warnings and other notices (RECOMMENDED for mod developers)
	if (COM_CheckParm("-developer"))
	{
		developer.value = developer.integer = 1;
		developer.string = "1";
	}

	if (COM_CheckParm("-developer2") || COM_CheckParm("-developer3"))
	{
		developer.value = developer.integer = 1;
		developer.string = "1";
		developer_extra.value = developer_extra.integer = 1;
		developer_extra.string = "1";
		developer_insane.value = developer_insane.integer = 1;
		developer_insane.string = "1";
		developer_memory.value = developer_memory.integer = 1;
		developer_memory.string = "1";
		developer_memorydebug.value = developer_memorydebug.integer = 1;
		developer_memorydebug.string = "1";
	}

	if (COM_CheckParm("-developer3"))
	{
		gl_paranoid.integer = 1;gl_paranoid.string = "1";
		gl_printcheckerror.integer = 1;gl_printcheckerror.string = "1";
	}

// COMMANDLINEOPTION: Console: -nostdout disables text output to the terminal the game was launched from
	if (COM_CheckParm("-nostdout"))
		sys_nostdout = 1;

	// used by everything
	Memory_Init();

	// initialize console command/cvar/alias/command execution systems
	Cmd_Init();

	// initialize memory subsystem cvars/commands
	Memory_Init_Commands();

	// initialize console and logging and its cvars/commands
	Con_Init();

	// initialize various cvars that could not be initialized earlier
	u8_Init();
	Curl_Init_Commands();
	Cmd_Init_Commands();
	Sys_Init_Commands();
	COM_Init_Commands();
	FS_Init_Commands();

	// initialize console window (only used by sys_win.c)
	Sys_InitConsole();

	// initialize the self-pack (must be before COM_InitGameType as it may add command line options)
	FS_Init_SelfPack();

	// detect gamemode from commandline options or executable name
	COM_InitGameType();

	// construct a version string for the corner of the console
	os = DP_OS_NAME;
	dpsnprintf (engineversion, sizeof (engineversion), "%s %s %s", gamename, os, buildstring);
	Con_Printf("%s\n", engineversion);

	// initialize process nice level
	Sys_InitProcessNice();

	// initialize ixtable
	Mathlib_Init();

	// initialize filesystem (including fs_basedir, fs_gamedir, -game, scr_screenshot_name)
	FS_Init();

	// register the cvars for session locking
	Host_InitSession();

	// must be after FS_Init
	Crypto_Init();
	Crypto_Init_Commands();

	NetConn_Init();
	Curl_Init();
	//PR_Init();
	//PR_Cmd_Init();
	PRVM_Init();
	Mod_Init();
	World_Init();
	SV_Init();
	V_Init(); // some cvars needed by server player physics (cl_rollangle etc)
	Host_InitCommands();
	Host_InitLocal();
	Host_ServerOptions();

	Thread_Init();

	if (cls.state == ca_dedicated)
		Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server (or disconnect all clients if running a server)");
	else
	{
		Con_DPrintf("Initializing client\n");

		R_Modules_Init();
		Palette_Init();
		MR_Init_Commands();
		VID_Shared_Init();
		VID_Init();
		Render_Init();
		S_Init();
		CDAudio_Init();
		Key_Init();
		CL_Init();
	}

	// save off current state of aliases, commands and cvars for later restore if FS_GameDir_f is called
	// NOTE: menu commands are freed by Cmd_RestoreInitState
	Cmd_SaveInitState();

	// FIXME: put this into some neat design, but the menu should be allowed to crash
	// without crashing the whole game, so this should just be a short-time solution

	// here comes the not so critical stuff
	if (setjmp(host_abortframe)) {
		return;
	}

	Host_AddConfigText();
	Cbuf_Execute();

	// if stuffcmds wasn't run, then quake.rc is probably missing, use default
	if (!host_stuffcmdsrun)
	{
		Cbuf_AddText("exec default.cfg\nexec " CONFIGFILENAME "\nexec autoexec.cfg\nstuffcmds\n");
		Cbuf_Execute();
	}

	// put up the loading image so the user doesn't stare at a black screen...
	SCR_BeginLoadingPlaque(true);

	if (cls.state != ca_dedicated)
	{
		MR_Init();
	}

	// check for special benchmark mode
// COMMANDLINEOPTION: Client: -benchmark <demoname> runs a timedemo and quits, results of any timedemo can be found in gamedir/benchmark.log (for example id1/benchmark.log)
	i = COM_CheckParm("-benchmark");
	if (i && i + 1 < com_argc)
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText(va(vabuf, sizeof(vabuf), "timedemo %s\n", com_argv[i + 1]));
		Cbuf_Execute();
	}

	// check for special demo mode
// COMMANDLINEOPTION: Client: -demo <demoname> runs a playdemo and quits
	i = COM_CheckParm("-demo");
	if (i && i + 1 < com_argc)
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\n", com_argv[i + 1]));
		Cbuf_Execute();
	}

// COMMANDLINEOPTION: Client: -capturedemo <demoname> captures a playdemo and quits
	i = COM_CheckParm("-capturedemo");
	if (i && i + 1 < com_argc)
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\ncl_capturevideo 1\n", com_argv[i + 1]));
		Cbuf_Execute();
	}

	if (cls.state == ca_dedicated || COM_CheckParm("-listen"))
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText("startmap_dm\n");
		Cbuf_Execute();
	}

	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText("togglemenu 1\n");
		Cbuf_Execute();
	}

	Con_DPrint("========Initialized=========\n");

	//Host_StartVideo();

	if (cls.state != ca_dedicated)
		SV_StartThread();
}
Ejemplo n.º 29
0
/*
================
SV_SpawnServer

Change the server to a new map, taking all connected
clients along with it.

This is only called from the SV_Map_f() function.
================
*/
void SV_SpawnServer (char *mapname, qbool devmap, char* entityfile)
{
    extern func_t ED_FindFunctionOffset (char *name);

    edict_t *ent;
    int i;

    extern cvar_t sv_loadentfiles, sv_loadentfiles_dir;
    char *entitystring;
    char oldmap[MAP_NAME_LEN];
    extern qbool	sv_allow_cheats;
    extern cvar_t	sv_cheats, sv_paused, sv_bigcoords;
#ifndef SERVERONLY
    extern void CL_ClearState (void);
#endif

    // store old map name
    snprintf (oldmap, MAP_NAME_LEN, "%s", sv.mapname);

    Con_DPrintf ("SpawnServer: %s\n",mapname);

#ifndef SERVERONLY
    // As client+server we do it here.
    // As serveronly we do it in NET_Init().
    NET_InitServer();
#endif

    SV_SaveSpawnparms ();
    SV_LoadAccounts();

#ifdef USE_PR2
    // remove bot clients
    for (i = 0; i < MAX_CLIENTS; i++)
    {
        if( sv_vm && svs.clients[i].isBot )
        {
            svs.clients[i].old_frags = 0;
            svs.clients[i].edict->v.frags = 0.0;
            svs.clients[i].name[0] = 0;
            svs.clients[i].state = cs_free;
            Info_RemoveAll(&svs.clients[i]._userinfo_ctx_);
            Info_RemoveAll(&svs.clients[i]._userinfoshort_ctx_);
            SV_FullClientUpdate(&svs.clients[i], &sv.reliable_datagram);
            svs.clients[i].isBot = 0;
        }
    }

#endif

    // Shutdown game.
    PR_GameShutDown();
    PR_UnLoadProgs();

    svs.spawncount++; // any partially connected client will be restarted

#ifndef SERVERONLY
    com_serveractive = false;
#endif
    sv.state = ss_dead;
    sv.paused = false;
    Cvar_SetROM(&sv_paused, "0");

    Host_ClearMemory();

#ifdef FTE_PEXT_FLOATCOORDS
    if (sv_bigcoords.value)
    {
        msg_coordsize = 4;
        msg_anglesize = 2;
    }
    else
    {
        msg_coordsize = 2;
        msg_anglesize = 1;
    }
#endif

    if ((int)coop.value)
        Cvar_Set (&deathmatch, "0");
    current_skill = (int) (skill.value + 0.5);
    if (current_skill < 0)
        current_skill = 0;
    Cvar_Set (&skill, va("%d", current_skill));
    if (current_skill > 3)
        current_skill = 3;

    if ((sv_cheats.value || devmap) && !sv_allow_cheats) {
        sv_allow_cheats = true;
        Info_SetValueForStarKey (svs.info, "*cheats", "ON", MAX_SERVERINFO_STRING);
    }
    else if ((!sv_cheats.value && !devmap) && sv_allow_cheats) {
        sv_allow_cheats = false;
        Info_SetValueForStarKey (svs.info, "*cheats", "", MAX_SERVERINFO_STRING);
    }


    // wipe the entire per-level structure
    // NOTE: this also set sv.mvdrecording to false, so calling SV_MVD_Record() at end of function
    memset (&sv, 0, sizeof(sv));


    sv.datagram.maxsize = sizeof(sv.datagram_buf);
    sv.datagram.data = sv.datagram_buf;
    sv.datagram.allowoverflow = true;

    sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf);
    sv.reliable_datagram.data = sv.reliable_datagram_buf;

    sv.multicast.maxsize = sizeof(sv.multicast_buf);
    sv.multicast.data = sv.multicast_buf;

    sv.signon.maxsize = sizeof(sv.signon_buffers[0]);
    sv.signon.data = sv.signon_buffers[0];
    sv.num_signon_buffers = 1;

    sv.time = 1.0;

    // load progs to get entity field count
    // which determines how big each edict is
    // and allocate edicts

    PR_LoadProgs ();
#ifdef WITH_NQPROGS
    PR_InitPatchTables();
#endif
    PR_InitProg();

    for (i = 0; i < MAX_EDICTS; i++)
    {
        ent = EDICT_NUM(i);
        ent->e = &sv.sv_edicts[i]; // assigning ->e field in each edict_t
        ent->e->entnum = i;
        ent->e->area.ed = ent; // yeah, pretty funny, but this help to find which edict_t own this area (link_t)
    }

    fofs_items2 = ED_FindFieldOffset ("items2"); // ZQ_ITEMS2 extension
    fofs_maxspeed = ED_FindFieldOffset ("maxspeed");
    fofs_gravity = ED_FindFieldOffset ("gravity");
    fofs_movement = ED_FindFieldOffset ("movement");
    fofs_vw_index = ED_FindFieldOffset ("vw_index");
    fofs_hideentity = ED_FindFieldOffset ("hideentity");
    fofs_trackent = ED_FindFieldOffset ("trackent");

    // find optional QC-exported functions.
    // we have it here, so we set it to NULL in case of PR2 progs.
    mod_SpectatorConnect = ED_FindFunctionOffset ("SpectatorConnect");
    mod_SpectatorThink = ED_FindFunctionOffset ("SpectatorThink");
    mod_SpectatorDisconnect = ED_FindFunctionOffset ("SpectatorDisconnect");
    mod_ChatMessage = ED_FindFunctionOffset ("ChatMessage");
    mod_UserInfo_Changed = ED_FindFunctionOffset ("UserInfo_Changed");
    mod_ConsoleCmd = ED_FindFunctionOffset ("ConsoleCmd");
    mod_UserCmd = ED_FindFunctionOffset ("UserCmd");
    mod_localinfoChanged = ED_FindFunctionOffset ("localinfoChanged");
    GE_ClientCommand = ED_FindFunctionOffset ("GE_ClientCommand");
    GE_PausedTic = ED_FindFunctionOffset ("GE_PausedTic");
    GE_ShouldPause = ED_FindFunctionOffset ("GE_ShouldPause");

    // leave slots at start for clients only
    sv.num_edicts = MAX_CLIENTS+1;
    for (i=0 ; i<MAX_CLIENTS ; i++)
    {
        ent = EDICT_NUM(i+1);
        // restore client name.
        ent->v.netname = PR_SetString(svs.clients[i].name);
        // reserve edict.
        svs.clients[i].edict = ent;
        //ZOID - make sure we update frags right
        svs.clients[i].old_frags = 0;
    }

    // fill sv.mapname and sv.modelname with new map name
    strlcpy (sv.mapname, mapname, sizeof(sv.mapname));
    snprintf (sv.modelname, sizeof(sv.modelname), "maps/%s.bsp", sv.mapname);
#ifndef SERVERONLY
    // set cvar
    Cvar_ForceSet (&host_mapname, mapname);
#endif

    if (!(sv.worldmodel = CM_LoadMap (sv.modelname, false, &sv.map_checksum, &sv.map_checksum2))) // true if bad map
    {
        Con_Printf ("Cant load map %s, falling back to %s\n", mapname, oldmap);

        // fill mapname, sv.mapname and sv.modelname with old map name
        strlcpy (sv.mapname, oldmap, sizeof(sv.mapname));
        snprintf (sv.modelname, sizeof(sv.modelname), "maps/%s.bsp", sv.mapname);
        mapname = oldmap;

        // and re-load old map
        sv.worldmodel = CM_LoadMap (sv.modelname, false, &sv.map_checksum, &sv.map_checksum2);

        // this should never happen
        if (!sv.worldmodel)
            SV_Error ("CM_LoadMap: bad map");
    }

    sv.map_checksum2 = Com_TranslateMapChecksum (sv.mapname, sv.map_checksum2);

    SV_ClearWorld (); // clear physics interaction links

#ifdef USE_PR2
    if ( sv_vm )
    {
        sv.sound_precache[0] = "";
        sv.model_precache[0] = "";
    }
    else
#endif

    {
        sv.sound_precache[0] = pr_strings;
        sv.model_precache[0] = pr_strings;
    }
    sv.model_precache[1] = sv.modelname;
    sv.models[1] = sv.worldmodel;
    for (i=1 ; i< CM_NumInlineModels() ; i++)
    {
        sv.model_precache[1+i] = localmodels[i];
        sv.models[i+1] =  CM_InlineModel (localmodels[i]);
    }

    //check player/eyes models for hacks
    sv.model_player_checksum = SV_CheckModel("progs/player.mdl");
    sv.eyes_player_checksum = SV_CheckModel("progs/eyes.mdl");

    //
    // spawn the rest of the entities on the map
    //

    // precache and static commands can be issued during
    // map initialization
    sv.state = ss_loading;
#ifndef SERVERONLY
    com_serveractive = true;
#endif

    ent = EDICT_NUM(0);
    ent->e->free = false;
    ent->v.model = PR_SetString(sv.modelname);
    ent->v.modelindex = 1;		// world model
    ent->v.solid = SOLID_BSP;
    ent->v.movetype = MOVETYPE_PUSH;

    // information about the server
    ent->v.netname = PR_SetString(VersionStringFull());
    ent->v.targetname = PR_SetString(SERVER_NAME);
    ent->v.impulse = VERSION_NUM;
    ent->v.items = pr_numbuiltins - 1;

    PR_GLOBAL(mapname) = PR_SetString(sv.mapname);
    // serverflags are for cross level information (sigils)
    PR_GLOBAL(serverflags) = svs.serverflags;
    if (pr_nqprogs)
    {
        pr_globals[35] = deathmatch.value;
        pr_globals[36] = coop.value;
        pr_globals[37] = teamplay.value;
        NQP_Reset ();
    }

    if (pr_nqprogs)
    {
        // register the cvars that NetQuake provides for mod use
        const char **var, *nqcvars[] = {"gamecfg", "scratch1", "scratch2", "scratch3", "scratch4",
                                        "saved1", "saved2", "saved3", "saved4", "savedgamecfg", "temp1", NULL
                                       };
        for (var = nqcvars; *var; var++)
            Cvar_Create((char *)/*stupid const warning*/ *var, "0", 0);
    }

    // run the frame start qc function to let progs check cvars
    if (!pr_nqprogs)
        SV_ProgStartFrame ();

    // ********* External Entity support (.ent file(s) in gamedir/maps) pinched from ZQuake *********
    // load and spawn all other entities
    entitystring = NULL;
    if ((int)sv_loadentfiles.value)
    {
        char ent_path[1024] = {0};

        if (!entityfile || !entityfile[0])
            entityfile = sv.mapname;

        // first try maps/sv_loadentfiles_dir/
        if (sv_loadentfiles_dir.string[0])
        {
            snprintf(ent_path, sizeof(ent_path), "maps/%s/%s.ent", sv_loadentfiles_dir.string, entityfile);
            entitystring = (char *) FS_LoadHunkFile(ent_path, NULL);
        }

        // try maps/ if not loaded yet.
        if (!entitystring)
        {
            snprintf(ent_path, sizeof(ent_path), "maps/%s.ent", entityfile);
            entitystring = (char *) FS_LoadHunkFile(ent_path, NULL);
        }

        if (entitystring) {
            Con_DPrintf ("Using entfile %s\n", ent_path);
        }
    }

    if (!entitystring) {
        entitystring = CM_EntityString();
    }

    PR_LoadEnts(entitystring);
    // ********* End of External Entity support code *********

    // look up some model indexes for specialized message compression
    SV_FindModelNumbers ();

    // all spawning is completed, any further precache statements
    // or prog writes to the signon message are errors
    sv.state = ss_active;

    // run two frames to allow everything to settle
    SV_Physics ();
    sv.time += 0.1;
    SV_Physics ();
    sv.time += 0.1;
    sv.old_time = sv.time;

    // save movement vars
    SV_SetMoveVars();

    // create a baseline for more efficient communications
    SV_CreateBaseline ();
    sv.signon_buffer_size[sv.num_signon_buffers-1] = sv.signon.cursize;

    Info_SetValueForKey (svs.info, "map", sv.mapname, MAX_SERVERINFO_STRING);

    // calltimeofday.
    {
        extern void PF_calltimeofday (void);
        pr_global_struct->time = sv.time;
        pr_global_struct->self = 0;

        PF_calltimeofday();
    }

    Con_DPrintf ("Server spawned.\n");

    // we change map - clear whole demo struct and sent initial state to all dest if any (for QTV only I thought)
    SV_MVD_Record(NULL, true);

#ifndef SERVERONLY
    CL_ClearState ();
#endif
}
Ejemplo n.º 30
0
void VID_Finish (void)
{
	qboolean vid_usevsync;

	// handle changes of the vsync option
	vid_usevsync = (vid_vsync.integer && !cls.timedemo);
	if (vid_usingvsync != vid_usevsync)
	{
		GLint sync = (vid_usevsync ? 1 : 0);

		if (qaglSetInteger(context, AGL_SWAP_INTERVAL, &sync) == GL_TRUE)
		{
			vid_usingvsync = vid_usevsync;
			Con_DPrintf("Vsync %s\n", vid_usevsync ? "activated" : "deactivated");
		}
		else
			Con_Printf("ERROR: can't %s vsync\n", vid_usevsync ? "activate" : "deactivate");
	}

	if (!vid_hidden)
	{
		if (r_speeds.integer == 2 || gl_finish.integer)
			GL_Finish();
		qaglSwapBuffers(context);
	}
	VID_UpdateGamma(false, GAMMA_TABLE_SIZE);

	if (apple_multithreadedgl.integer)
	{
		if (!multithreadedgl)
		{
			if(qCGLGetCurrentContext && qCGLEnable && qCGLDisable)
			{
				CGLContextObj ctx = qCGLGetCurrentContext();
				CGLError e = qCGLEnable(ctx, kCGLCEMPEngine);
				if(e == kCGLNoError)
					multithreadedgl = true;
				else
				{
					Con_Printf("WARNING: can't enable multithreaded GL, error %d\n", (int) e);
					Cvar_SetValueQuick(&apple_multithreadedgl, 0);
				}
			}
			else
			{
				Con_Printf("WARNING: can't enable multithreaded GL, CGL functions not present\n");
				Cvar_SetValueQuick(&apple_multithreadedgl, 0);
			}
		}
	}
	else
	{
		if (multithreadedgl)
		{
			if(qCGLGetCurrentContext && qCGLEnable && qCGLDisable)
			{
				CGLContextObj ctx = qCGLGetCurrentContext();
				qCGLDisable(ctx, kCGLCEMPEngine);
				multithreadedgl = false;
			}
		}
	}
}