Пример #1
0
/*
=============
RunThreadsOn
=============
*/
void RunThreadsOn (threadfunc_t func)
{
	pthread_t	work_threads[MAX_THREADS];
	void		*status;
	pthread_attr_t	attrib;
	long		i;

	if (numthreads <= 1)
	{
		func (NULL);
		return;
	}

	if (pthread_attr_init (&attrib) == -1)
		COM_Error ("pthread_attr_init failed");
	if (pthread_attr_setstacksize (&attrib, stacksiz) == -1)
		COM_Error ("pthread_attr_setstacksize failed");

	workfunc = func;

	for (i = 0; i < numthreads; i++)
	{
		if (pthread_create (&work_threads[i], &attrib,
					ThreadWorkerFunc,
					(void *)i) == -1)
			COM_Error ("pthread_create failed");
	}

	for (i = 0; i < numthreads; i++)
	{
		if (pthread_join (work_threads[i], &status) == -1)
			COM_Error ("pthread_join failed");
	}
}
Пример #2
0
void InitThreads (int wantthreads, size_t needstack)
{
	pthread_mutexattr_t mattrib;

	if (needstack != 0)
		stacksiz = needstack;
	else	stacksiz = DEFAULT_STACKSIZ;

	numthreads = wantthreads;
	if (numthreads < 0)
		numthreads = Thread_GetNumCPUS ();
	if (numthreads < 1)
		numthreads = 1;
	if (numthreads > MAX_THREADS)
		numthreads = MAX_THREADS;

	printf ("Setup for %d threads, 0x%x stack size\n",
			numthreads, (unsigned int)stacksiz);
	if (numthreads <= 1)
		return;

	my_mutex = (pthread_mutex_t *) SafeMalloc (sizeof (*my_mutex));
	if (pthread_mutexattr_init (&mattrib) == -1)
		COM_Error ("pthread_mutex_attr_init failed");
	if (pthread_mutex_init (my_mutex, &mattrib) == -1)
		COM_Error ("pthread_mutex_init failed");
}
Пример #3
0
/*
=============
RunThreadsOn
=============
*/
void RunThreadsOn (threadfunc_t func)
{
	pid_t		pid[MAX_THREADS];
	long		i;

	if (numthreads <= 1)
	{
		func (NULL);
		return;
	}

	init_lock (&lck);
	workfunc = func;

	for (i = 0; i < numthreads - 1; i++)
	{
		pid[i] = sprocsp (ThreadWorkerFunc, PR_SALL, (void *)i,
				  NULL, stacksiz);
		if (pid[i] == -1)
		{
			perror ("sproc");
			COM_Error ("sproc failed");
		}
	}

	func ((void *)i);

	for (i = 0; i < numthreads - 1; i++)
		wait (NULL);
}
Пример #4
0
/*
============
WriteFiles

  Generates files.dat, which contains all of the
  data files actually used by the game, to be
  processed by qfiles.exe
============
*/
static void WriteFiles (void)
{
	FILE	*f;
	int		i;
	char	filename[1024];

	q_snprintf (filename, sizeof(filename), "%sfiles.dat", sourcedir);
	f = fopen (filename, "w");
	if (!f)
		COM_Error ("Couldn't open %s", filename);

	fprintf (f, "%i\n", numsounds);
	for (i = 0; i < numsounds; i++)
		fprintf (f, "%i %s\n", precache_sounds_block[i], precache_sounds[i]);

	fprintf (f, "%i\n", nummodels);
	for (i = 0; i < nummodels; i++)
		fprintf (f, "%i %s\n", precache_models_block[i], precache_models[i]);

	fprintf (f, "%i\n", numfiles);
	for (i = 0; i < numfiles; i++)
		fprintf (f, "%i %s\n", precache_files_block[i], precache_files[i]);

	fclose (f);
}
Пример #5
0
BOOL    COM_Write( int item, void *buff, int size )
{
BOOL    ok=TRUE;
DWORD   done;

    if( COM_Handle(item) == INVALID_HANDLE_VALUE )
    {
        COM_errorf("COM_Write(...) Invalid handle.\n");
        return(FALSE);
    }

    if( !WriteFile(COM_Item[item].comH,buff,size,&done,NULL) )
    {
        COM_errorf("COM_Write(COM%d) WriteFile() Failed (%s).\n",COM_Item[item].comX,COM_Error());
        ok = FALSE;
    }
    else
    if( size != (int)done )
    {
        COM_errorf("COM_Write(COM%d) WriteFile() Incomplete (size=%d, done=%ld).\n",COM_Item[item].comX,size,done);
        ok = FALSE;
    }

    return(ok);
}
Пример #6
0
int Q_WriteFileFromHandle (FILE *fromfile, const char *topath, size_t size)
{
	char	buf[COPY_READ_BUFSIZE];
	FILE	*out;
/*	off_t	remaining, count;*/
	size_t	remaining, count;
	char	temp[1024];

	strcpy (temp, topath);
	CreatePath (temp);

	out = fopen (topath, "wb");
	if (!out)
		COM_Error ("Unable to create file %s", topath);

	remaining = size;
	while (remaining)
	{
		if (remaining < sizeof(buf))
			count = remaining;
		else	count = sizeof(buf);

		if (fread(buf, 1, count, fromfile) != count)
			break;
		if (fwrite(buf, 1, count, out) != count)
			break;

		remaining -= count;
	}

	fclose (out);

	return (remaining == 0)? 0 : 1;
}
Пример #7
0
void Q_mkdir (const char *path)
{
	if (CreateDirectory(path, NULL) != 0)
		return;
	if (GetLastError() != ERROR_ALREADY_EXISTS)
		COM_Error ("Unable to create directory %s", path);
}
Пример #8
0
static void TestSingleLightFace (entity_t *light, lightinfo_t *l, const vec3_t faceoffset)
{
	vec_t	dist;
	vec_t	add;
	vec_t	*surf;
	vec3_t	rel;
	int	surf_r;
	int	surf_g;
	int	surf_b;
	int	c;

	VectorSubtract (light->origin, bsp_origin, rel);
	dist = scaledDistance((DotProduct(rel, l->facenormal) - l->facedist), light);

	// don't bother with lights behind the surface
	if (dist <= 0)
		return;

	// don't bother with light too far away
	if (dist > abs(light->light))
	{
		return;
	}

	// mfah - find the light color based on the surface name
	FindTexlightColor (&surf_r, &surf_g, &surf_b, l->texname);

	surf = l->surfpt[0];

	// we could speed the whole thing up drastically by checking only
	// the first and last point of each face - trouble is, any large
	// faces may have a light that only hits the middle.
	for (c = 0 ; c < l->numsurfpt ; c++, surf+=3)
	{
		if (surf > l->surfpt[SINGLEMAP - 1])
			COM_Error ("%s: surf out of bounds (numsurfpt=%d)", __thisfunc__, l->numsurfpt);
		dist = scaledDistance(CastRay(light->origin, surf), light);

		if (dist < 0)
			continue;	// light doesn't reach

		add = scaledLight(CastRay(light->origin, surf), light);

		if (add < (light->light / 3))
			continue;

		// normal light - other lights already have a color assigned
		// to them from when they were initially loaded
		// this will give madly high color values here so we will
		// scale them down later on
		light->lightcolor[0] = light->lightcolor[0] + surf_r;
		light->lightcolor[1] = light->lightcolor[1] + surf_g;
		light->lightcolor[2] = light->lightcolor[2] + surf_b;

		// speed up the checking process some more - if we have one hit
		// on a face, all other hits on the same face are just going to
		// give the same result - so we can return now.
		return;
	}
}
Пример #9
0
const char *Q_FindFirstFile (const char *path, const char *pattern)
{
	BPTR newdir;

	if (apath)
		COM_Error ("FindFirst without FindClose");

	apath = (struct AnchorPath *) AllocVec (sizeof(struct AnchorPath) + PATH_SIZE, MEMF_CLEAR);
	if (!apath)
		return NULL;

	apath->ap_Strlen = PATH_SIZE;
	apath->ap_BreakBits = 0;
	apath->ap_Flags = 0;  /* APF_DOWILD */

	newdir = Lock((const STRPTR) path, SHARED_LOCK);
	if (newdir)
		oldcurrentdir = CurrentDir(newdir);
	else
	{
		FreeVec(apath);
		apath = NULL;
		return NULL;
	}

	pattern_str = pattern_helper (pattern);

	if (MatchFirst((const STRPTR) pattern_str, apath) == 0)
	{
	    if (apath->ap_Info.fib_DirEntryType < 0)
		return (const char *) (apath->ap_Info.fib_FileName);
	}

	return Q_FindNextFile();
}
Пример #10
0
/*
===============
RunThreadsOn
===============
*/
void RunThreadsOn (threadfunc_t func)
{
	unsigned	IDThread;
	HANDLE	work_threads[MAX_THREADS];
	INT_PTR		i;

	if (numthreads <= 1)
	{
		func (NULL);
		return;
	}

	workfunc = func;

	for (i = 0; i < numthreads; i++)
	{
		work_threads[i] = (HANDLE) _beginthreadex(NULL, /* no security attributes */
			stacksiz,			/* stack size */
			ThreadWorkerFunc,		/* thread function */
			(void *) i,			/* thread function arg */
			0,				/* run immediately */
			&IDThread);

		if (!work_threads[i])
			COM_Error ("_beginthreadex () failed");
	}

	for (i = 0; i < numthreads; i++)
	{
		WaitForSingleObject(work_threads[i], INFINITE);
	}
}
Пример #11
0
/*
===============
RunThreadsOn
===============
*/
void RunThreadsOn (threadfunc_t func)
{
	LONG		i;

	if (numthreads <= 1)
	{
		work_threads[0] = -1;
		func (NULL);
		return;
	}

	workfunc = func;

	for (i = 0; i < numthreads; i++)
	{
		work_threads[i] = _beginthread(ThreadWorkerFunc, NULL, stacksiz, (void *)i);
		if (work_threads[i] == -1)
			COM_Error ("_beginthread() failed");
	}

	for (i = 0; i < numthreads; i++)
	{
		while (work_threads[i] != -1)
			DosSleep (100);
	}
}
Пример #12
0
void Q_mkdir (const char *path)
{
	int rc = mkdir (path, 0777);
	if (rc != 0 && errno == EEXIST)
		rc = 0;
	if (rc != 0)
		COM_Error ("Unable to create directory %s", path);
}
Пример #13
0
/*
================
CalcFaceExtents

Fills in s->texmins[] and s->texsize[]
also sets exactmins[] and exactmaxs[]
================
*/
static void CalcFaceExtents (lightinfo_t *l, const vec3_t faceoffset, qboolean fail)
{
	dface_t	*s;
	vec_t	mins[2], maxs[2], val;
	int		i, j, e;
	dvertex_t	*v;
	texinfo_t	*tex;

	s = l->face;

	mins[0] = mins[1] = 999999;
	maxs[0] = maxs[1] = -99999;

	tex = &texinfo[s->texinfo];

	for (i = 0 ; i < s->numedges ; i++)
	{
		e = dsurfedges[s->firstedge+i];
		if (e >= 0)
			v = dvertexes + dedges[e].v[0];
		else
			v = dvertexes + dedges[-e].v[1];

		for (j = 0 ; j < 2 ; j++)
		{
			val =	((double)v->point[0] + faceoffset[0]) * (double)tex->vecs[j][0] +
				((double)v->point[1] + faceoffset[1]) * (double)tex->vecs[j][1] +
				((double)v->point[2] + faceoffset[2]) * (double)tex->vecs[j][2] +
				(double)tex->vecs[j][3];

			if (val < mins[j])
				mins[j] = val;
			if (val > maxs[j])
				maxs[j] = val;
		}
	}

	for (i = 0 ; i < 2 ; i++)
	{
		l->exactmins[i] = mins[i];
		l->exactmaxs[i] = maxs[i];

		mins[i] = floor(mins[i]/16);
		maxs[i] = ceil(maxs[i]/16);

		/*
		l->texmins[i] = (int)floor(mins[i]);
		l->texsize[i] = (int)floor(maxs[i] - mins[i]);
		*/
		l->texmins[i] = mins[i];
		l->texsize[i] = maxs[i] - mins[i];

		if (fail && l->texsize[i] > 17)
			COM_Error ("Bad surface extents");
	}
}
Пример #14
0
/*
================
CalcFaceVectors

Fills in texorg, worldtotex. and textoworld
================
*/
static void CalcFaceVectors (lightinfo_t *l)
{
	texinfo_t	*tex;
	int			i, j;
	vec3_t	texnormal;
	float	distscale;
	vec_t	dist, len;

	tex = &texinfo[l->face->texinfo];

// convert from float to vec_t
	for (i = 0 ; i < 2 ; i++)
	{
		for (j = 0 ; j < 3 ; j++)
			l->worldtotex[i][j] = tex->vecs[i][j];
	}

// calculate a normal to the texture axis.  points can be moved along this
// without changing their S/T
	texnormal[0] = tex->vecs[1][1]*tex->vecs[0][2] - tex->vecs[1][2]*tex->vecs[0][1];
	texnormal[1] = tex->vecs[1][2]*tex->vecs[0][0] - tex->vecs[1][0]*tex->vecs[0][2];
	texnormal[2] = tex->vecs[1][0]*tex->vecs[0][1] - tex->vecs[1][1]*tex->vecs[0][0];
	VectorNormalize (texnormal);

// flip it towards plane normal
	distscale = DotProduct (texnormal, l->facenormal);
	if (!distscale)
		COM_Error ("Texture axis perpendicular to face");
	if (distscale < 0)
	{
		distscale = -distscale;
		VectorNegate (texnormal, texnormal);
	}

// distscale is the ratio of the distance along the texture normal to
// the distance along the plane normal
	distscale = 1/distscale;

	for (i = 0 ; i < 2 ; i++)
	{
		len = VectorLength (l->worldtotex[i]);
		dist = DotProduct (l->worldtotex[i], l->facenormal);
		dist *= distscale;
		VectorMA (l->worldtotex[i], -dist, texnormal, l->textoworld[i]);
		VectorScale (l->textoworld[i], (1/len)*(1/len), l->textoworld[i]);
	}

// calculate texorg on the texture plane
	for (i = 0 ; i < 3 ; i++)
		l->texorg[i] = -tex->vecs[0][3]* l->textoworld[0][i] - tex->vecs[1][3] * l->textoworld[1][i];

// project back to the face plane
	dist = DotProduct (l->texorg, l->facenormal) - l->facedist - 1;
	dist *= distscale;
	VectorMA (l->texorg, -dist, texnormal, l->texorg);
}
Пример #15
0
/*
==============
SafeOpenRead

==============
*/
FILE *SafeOpenRead (const char *filename)
{
	FILE	*f;

	f = fopen(filename, "rb");
	if (!f)
		COM_Error("Error opening %s: %s", filename, strerror(errno));

	return f;
}
Пример #16
0
void Q_getwd (char *out, size_t size, qboolean trailing_dirsep)
{
	ULONG l, drv;

	if (size < 8) COM_Error ("Too small buffer for getcwd");
	l = size - 3;
	if (DosQueryCurrentDir(0, (PBYTE) out + 3, &l) != NO_ERROR)
		COM_Error ("Couldn't determine current directory");
	DosQueryCurrentDisk(&drv, &l);
	out[0] = drv + 'A' - 1;
	out[1] = ':';
	out[2] = '\\';

	if (!trailing_dirsep)
		return;
	l = strlen(out);
	if (out[l - 1] == '\\' || out[l - 1] == '/')
		return;
	qerr_strlcat(__thisfunc__, __LINE__, out, "\\", size);
}
Пример #17
0
void Q_mkdir (const char *path)
{
	FILESTATUS3 fs;
	APIRET rc = DosCreateDir(path, NULL);
	if (rc == NO_ERROR) return;
	if ((DosQueryPathInfo(path, FIL_STANDARD, &fs, sizeof(fs)) == NO_ERROR) &&
						  (fs.attrFile & FILE_DIRECTORY)) {
		return; /* dir exists */
	}
	COM_Error ("Unable to create directory %s", path);
}
Пример #18
0
BOOL    COM_Close( HANDLE comH )
{
BOOL    ok=TRUE;

    if( !CloseHandle(comH) )
    {
        COM_errorf("COM_Close(...) CloseHandle() Failed (%s).\n",COM_Error());
        ok = FALSE;
    }

    return(ok);
}
Пример #19
0
const char *Q_FindFirstFile (const char *path, const char *pattern)
{
	if (findhandle != INVALID_HANDLE_VALUE)
		COM_Error ("FindFirst without FindClose");
	q_snprintf (findstr, sizeof(findstr), "%s/%s", path, pattern);
	findhandle = FindFirstFile(findstr, &finddata);
	if (findhandle == INVALID_HANDLE_VALUE)
		return NULL;
	if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		return Q_FindNextFile();
	return finddata.cFileName;
}
Пример #20
0
byte *GetFileSpace (int size)
{
	byte	*buf;

	ThreadLock();
	file_p = (byte *)(((intptr_t)file_p + 3) & ~3);
	buf = file_p;
	file_p += size;
	ThreadUnlock();
	if (file_p > file_end)
		COM_Error ("%s: overrun", __thisfunc__);
	return buf;
}
Пример #21
0
void Q_getwd (char *out, size_t size, qboolean trailing_dirsep)
{
	size_t sz;

	if (getcwd(out, size) == NULL)
		COM_Error ("Couldn't determine current directory");
	if (!trailing_dirsep)
		return;
	sz = strlen(out);
	if (!sz || out[sz - 1] == '/')
		return;
	qerr_strlcat(__thisfunc__, __LINE__, out, "/", size);
}
Пример #22
0
/*
============
Q_CopyFile

Used to archive source files
============
*/
#define	COPY_READ_BUFSIZE		8192	/* BUFSIZ */
int Q_CopyFile (const char *frompath, const char *topath)
{
	char	buf[COPY_READ_BUFSIZE];
	FILE	*in, *out;
	char	temp[1024];
/*	off_t	remaining, count;*/
	size_t	remaining, count;

	strcpy (temp, topath);
	CreatePath (temp);

	in = fopen (frompath, "rb");
	if (!in)
		COM_Error ("Unable to open file %s", frompath);
	out = fopen (topath, "wb");
	if (!out)
		COM_Error ("Unable to create file %s", topath);

	remaining = Q_filelength (in);
	while (remaining)
	{
		if (remaining < sizeof(buf))
			count = remaining;
		else	count = sizeof(buf);

		if (fread(buf, 1, count, in) != count)
			break;
		if (fwrite(buf, 1, count, out) != count)
			break;

		remaining -= count;
	}

	fclose (in);
	fclose (out);

	return (remaining == 0)? 0 : 1;
}
Пример #23
0
const char *Q_FindFirstFile (const char *path, const char *pattern)
{
	if (findhandle == 0)
		COM_Error ("FindFirst without FindClose");

	q_snprintf (findstr, sizeof(findstr), "%s/%s", path, pattern);
	memset (&finddata, 0, sizeof(finddata));

	findhandle = findfirst(findstr, &finddata, FA_ARCH | FA_RDONLY);
	if (findhandle == 0)
		return finddata.ff_name;

	return NULL;
}
Пример #24
0
void Q_mkdir (const char *path)
{
	BPTR lock = CreateDir((const STRPTR) path);

	if (lock)
	{
		UnLock(lock);
		return;
	}
	if (IoErr() == ERROR_OBJECT_EXISTS)
		return;

	COM_Error("Unable to create directory %s", path);
}
Пример #25
0
static def_t *PR_DefForFieldOfs (gofs_t ofs)
{
	def_t	*d;

	for (d = pr.def_head.next; d; d = d->next)
	{
		if (d->type->type != ev_field)
			continue;
		if (((int *)pr_globals)[d->ofs] == ofs)
			return d;
	}
	COM_Error ("%s: couldn't find %i", __thisfunc__, ofs);
	return NULL;
}
Пример #26
0
void Q_getwd (char *out, size_t size, qboolean trailing_dirsep)
{
	size_t sz;

	sz = GetCurrentDirectory(size, out);
	if (sz == 0 || sz > size)
		COM_Error ("Couldn't determine current directory");
	if (!trailing_dirsep)
		return;
	sz = strlen(out);
	if (!sz || out[sz - 1] == '\\' || out[sz - 1] == '/')
		return;
	qerr_strlcat(__thisfunc__, __LINE__, out, "\\", size);
}
Пример #27
0
void Q_mkdir (const char *path)
{
	int rc = mkdir (path, 0777);
	if (rc != 0 && errno == EEXIST)
	{
		struct stat st;
		if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
			rc = 0;
	}
	if (rc != 0)
	{
		rc = errno;
		COM_Error ("Unable to create directory %s: %s", path, strerror(rc));
	}
}
Пример #28
0
int Thread_GetNumCPUS (void)
{
	SYSTEM_INFO info;
	OSVERSIONINFO vinfo;
	int numcpus;

	vinfo.dwOSVersionInfoSize = sizeof(vinfo);
	if (!GetVersionEx (&vinfo))
		COM_Error ("Couldn't get OS info");
	if (vinfo.dwMajorVersion < 4 || vinfo.dwPlatformId < VER_PLATFORM_WIN32_NT)
		return 1;
	GetSystemInfo(&info);
	numcpus = info.dwNumberOfProcessors;
	return (numcpus < 1) ? 1 : numcpus;
}
Пример #29
0
void Q_getwd (char *out, size_t size, qboolean trailing_dirsep)
{
#if 0
	qerr_strlcpy(__thisfunc__, __LINE__, out, "PROGDIR:", size);
#else
	size_t sz;
	if (NameFromLock(((struct Process *) FindTask(NULL))->pr_CurrentDir, (STRPTR) out, size) == 0)
		COM_Error ("Couldn't determine current directory");
	if (!trailing_dirsep)
		return;
	sz = strlen(out);
	if (!sz || out[sz - 1] == ':' || out[sz - 1] == '/')
		return;
	qerr_strlcat(__thisfunc__, __LINE__, out, "/", size);
#endif
}
Пример #30
0
void LoadTriangleList(const char *fileName, triangle_t **triList, int *triangleCount)
{
	FILE	*input;

	q_strlcpy(InputFileName, fileName, sizeof(InputFileName));

	StripExtension(InputFileName);
	q_strlcat(InputFileName, ".asc", sizeof(InputFileName));
	if ((input = fopen(InputFileName, "rb")) != NULL)
	{
		fclose(input);
		LoadASC(InputFileName, triList, triangleCount);
		return;
	}

	StripExtension(InputFileName);
	q_strlcat(InputFileName, ".hrc", sizeof(InputFileName));
	if ((input = fopen(InputFileName, "rb")) != NULL)
	{
		fclose(input);
		LoadHRC(InputFileName, triList, triangleCount);
		return;
	}

	StripExtension(InputFileName);
	q_strlcat(InputFileName, ".htr", sizeof(InputFileName));
	if ((input = fopen(InputFileName, "rb")) != NULL)
	{
		fclose(input);
		LoadHTR(InputFileName, triList, triangleCount);
		return;
	}

	StripExtension(InputFileName);
	q_strlcat(InputFileName, ".tri", sizeof(InputFileName));
	if ((input = fopen(InputFileName, "rb")) != NULL)
	{
		LoadTRI(input, triList, triangleCount);
		fclose(input);
		return;
	}

	COM_Error("Could not open file '%s':\n"
		"No ASC, HRC, HTR, or TRI match.\n", fileName);
}