Beispiel #1
0
/*
===========
FillOutside

===========
*/
qboolean FillOutside (tree_t *tree, int hullnum)
{
	int			i;
	int			s;
	qboolean	inside;
	vec3_t		origin;

	qprintf ("----- FillOutside ----\n");

	if (nofill)
	{
		printf ("skipped\n");
		return false;
	}

	inside = false;
	for (i=1 ; i<num_entities ; i++)
	{
		GetVectorForKey (&entities[i], "origin", origin);

		if (DotProduct (origin, origin) >= 0.1)
		{
			if (PlaceOccupant (i, origin, tree->headnode))
				inside = true;
		}
	}

	if (!inside)
	{
		printf ("Hullnum %i: No entities in empty space -- no filling performed\n", hullnum);
		return false;
	}

	s = !(outside_node.portals->nodes[1] == &outside_node);

// first check to see if an occupied leaf is hit
	outleafs = 0;
	valid++;

	prevleaknode = NULL;

	if (RecursiveFillOutside (outside_node.portals->nodes[s], hullnum, false))
	{
		if (leakfile)
			fclose(leakfile);
		leakfile = NULL;
		if (!hullnum)
		{
			GetVectorForKey (&entities[hit_occupied], "origin", origin);

			qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
			qprintf ("reached occupant at: (%4.0f,%4.0f,%4.0f)\n", origin[0], origin[1], origin[2]);
			qprintf ("no filling performed\n");
			qprintf ("leak file written to %s\n", filename_pts);
			qprintf ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
		}

		// remove faces from filled in leafs
		ClearOutFaces (tree->headnode);
		return false;
	}

	// now go back and fill things in
	valid++;
	RecursiveFillOutside (outside_node.portals->nodes[s], hullnum, true);

	// remove faces from filled in leafs
	ClearOutFaces (tree->headnode);

	qprintf ("%4i outleafs\n", outleafs);
	return true;
}
Beispiel #2
0
/* initialize driver & display */
int drv_BuE_init(const char *section, const int quiet)
{
    WIDGET_CLASS wc;
    int ret;

    info("%s: %s", Name, "$Rev: 840 $");

    /* start display */
    if ((ret = drv_BuE_start(section)) != 0) {
	return ret;
    }

    /* display preferences */
    XRES = 5;			/* pixel width of one char  */
    YRES = 8;			/* pixel height of one char  */
    CHARS = 8;			/* number of user-defineable characters */

    /* real worker functions */
    switch (Protocol) {
    case 1:
	CHAR0 = 0;		/* ASCII of first user-defineable char */
	GOTO_COST = 6;		/* number of bytes a goto command requires */
	drv_generic_text_real_write = drv_BuE_MT_write;
	drv_generic_text_real_defchar = drv_BuE_MT_defchar;
	break;
    case 2:
	CHAR0 = 128;		/* ASCII of first user-defineable char */
	GOTO_COST = 6;		/* number of bytes a goto command requires */
	drv_generic_text_real_write = drv_BuE_CT_write;
	drv_generic_text_real_defchar = drv_BuE_CT_defchar;
	break;
    }

    if (!quiet) {
	char buffer[40];
	qprintf(buffer, sizeof(buffer), "%s %s", Name, Models[Model].name);
	if (drv_generic_text_greet(buffer, "www.bue.com")) {
	    sleep(3);
	    drv_BuE_clear();
	}
    }

    /* initialize generic text driver */
    if ((ret = drv_generic_text_init(section, Name)) != 0)
	return ret;

    /* initialize generic icon driver */
    if ((ret = drv_generic_text_icon_init()) != 0)
	return ret;

    /* initialize generic bar driver */
    if ((ret = drv_generic_text_bar_init(0)) != 0)
	return ret;

    /* add fixed chars to the bar driver */
    drv_generic_text_bar_add_segment(0, 0, 255, 32);	/* ASCII  32 = blank */
    drv_generic_text_bar_add_segment(255, 255, 255, 255);	/* ASCII 255 = block */

    /* register text widget */
    wc = Widget_Text;
    wc.draw = drv_generic_text_draw;
    widget_register(&wc);

    /* register icon widget */
    wc = Widget_Icon;
    wc.draw = drv_generic_text_icon_draw;
    widget_register(&wc);

    /* register bar widget */
    wc = Widget_Bar;
    wc.draw = drv_generic_text_bar_draw;
    widget_register(&wc);

    /* register plugins */
    AddFunction("LCD::contrast", -1, plugin_contrast);
    AddFunction("LCD::backlight", -1, plugin_backlight);
    AddFunction("LCD::gpo", -1, plugin_gpo);
    AddFunction("LCD::gpi", 1, plugin_gpi);
    AddFunction("LCD::adc", 0, plugin_adc);
    AddFunction("LCD::pwm", -1, plugin_pwm);

    return 0;
}
Beispiel #3
0
/*
=================
BrushBSP

The incoming list will be freed before exiting
=================
*/
tree_t *BrushBSP (bspbrush_t *brushlist, vec3_t mins, vec3_t maxs)
{
	node_t		*node;
	bspbrush_t	*b;
	int			c_faces, c_nonvisfaces;
	int			c_brushes;
	tree_t		*tree;
	int			i;
	vec_t		volume;

	qprintf ("--- BrushBSP ---\n");

	tree = AllocTree ();

	c_faces = 0;
	c_nonvisfaces = 0;
	c_brushes = 0;
	for (b=brushlist ; b ; b=b->next)
	{
		c_brushes++;

		volume = BrushVolume (b);
		if (volume < microvolume)
		{
			printf ("WARNING: entity %i, brush %i: microbrush\n",
				b->original->entitynum, b->original->brushnum);
		}

		for (i=0 ; i<b->numsides ; i++)
		{
			if (b->sides[i].bevel)
				continue;
			if (!b->sides[i].winding)
				continue;
			if (b->sides[i].texinfo == TEXINFO_NODE)
				continue;
			if (b->sides[i].visible)
				c_faces++;
			else
				c_nonvisfaces++;
		}

		AddPointToBounds (b->mins, tree->mins, tree->maxs);
		AddPointToBounds (b->maxs, tree->mins, tree->maxs);
	}

	qprintf ("%5i brushes\n", c_brushes);
	qprintf ("%5i visible faces\n", c_faces);
	qprintf ("%5i nonvisible faces\n", c_nonvisfaces);

	c_nodes = 0;
	c_nonvis = 0;
	node = AllocNode ();

	node->volume = BrushFromBounds (mins, maxs);

	tree->headnode = node;

	node = BuildTree_r (node, brushlist);
	qprintf ("%5i visible nodes\n", c_nodes/2 - c_nonvis);
	qprintf ("%5i nonvis nodes\n", c_nonvis);
	qprintf ("%5i leafs\n", (c_nodes+1)/2);
#if 0
{	// debug code
static node_t	*tnode;
vec3_t	p;

p[0] = -1469;
p[1] = -118;
p[2] = 119;
tnode = PointInLeaf (tree->headnode, p);
printf ("contents: %i\n", tnode->contents);
p[0] = 0;
}
#endif
	return tree;
}
Beispiel #4
0
/*
=====================
PatchMapDrawSurfs

Any patches that share an edge need to choose their
level of detail as a unit, otherwise the edges would
pull apart.
=====================
*/
void PatchMapDrawSurfs( entity_t *e ) {
	parseMesh_t			*pm;
	parseMesh_t			*check, *scan;
	mapDrawSurface_t	*ds;
	int					patchCount, groupCount;
	int					i, j, k, l, c1, c2;
	drawVert_t			*v1, *v2;
	vec3_t				bounds[2];
	byte				*bordering;
	parseMesh_t			*meshes[MAX_MAP_DRAW_SURFS];
	qboolean			grouped[MAX_MAP_DRAW_SURFS];
	byte				group[MAX_MAP_DRAW_SURFS];

	qprintf( "----- PatchMapDrawSurfs -----\n" );

	patchCount = 0;
	for ( pm = e->patches ; pm ; pm = pm->next  ) {
		meshes[patchCount] = pm;
		patchCount++;
	}

	if ( !patchCount ) {
		return;
	}
	bordering = malloc( patchCount * patchCount );
	memset( bordering, 0, patchCount * patchCount );

	// build the bordering matrix
	for ( k = 0 ; k < patchCount ; k++ ) {
		bordering[k*patchCount+k] = 1;

		for ( l = k+1 ; l < patchCount ; l++ ) {
			check = meshes[k];
			scan = meshes[l];
			c1 = scan->mesh.width * scan->mesh.height;
			v1 = scan->mesh.verts;

			for ( i = 0 ; i < c1 ; i++, v1++ ) {
				c2 = check->mesh.width * check->mesh.height;
				v2 = check->mesh.verts;
				for ( j = 0 ; j < c2 ; j++, v2++ ) {
					if ( fabs( v1->xyz[0] - v2->xyz[0] ) < 1.0
						&& fabs( v1->xyz[1] - v2->xyz[1] ) < 1.0
						&& fabs( v1->xyz[2] - v2->xyz[2] ) < 1.0 ) {
						break;
					}
				}
				if ( j != c2 ) {
					break;
				}
			}
			if ( i != c1 ) {
				// we have a connection
				bordering[k*patchCount+l] =
				bordering[l*patchCount+k] = 1;
			} else {
				// no connection
				bordering[k*patchCount+l] =
				bordering[l*patchCount+k] = 0;
			}

		}
	}

	// build groups
	memset( grouped, 0, sizeof(grouped) );
	groupCount = 0;
	for ( i = 0 ; i < patchCount ; i++ ) {
		if ( !grouped[i] ) {
			groupCount++;
		}

		// recursively find all patches that belong in the same group
		memset( group, 0, patchCount );
		GrowGroup_r( i, patchCount, bordering, group );

		// bound them
		ClearBounds( bounds[0], bounds[1] );
		for ( j = 0 ; j < patchCount ; j++ ) {
			if ( group[j] ) {
				grouped[j] = qtrue;
				scan = meshes[j];
				c1 = scan->mesh.width * scan->mesh.height;
				v1 = scan->mesh.verts;
				for ( k = 0 ; k < c1 ; k++, v1++ ) {
					AddPointToBounds( v1->xyz, bounds[0], bounds[1] );
				}
			}
		}

		// create drawsurf
		scan = meshes[i];
		scan->grouped = qtrue;
		ds = DrawSurfaceForMesh( &scan->mesh );
		ds->shaderInfo = scan->shaderInfo;
		VectorCopy( bounds[0], ds->lightmapVecs[0] );
		VectorCopy( bounds[1], ds->lightmapVecs[1] );
	}

	qprintf( "%5i patches\n", patchCount );
	qprintf( "%5i patch LOD groups\n", groupCount );
}
Beispiel #5
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void AddThread(void (*func)(int))
{
	thread_t *thread;

	if (numthreads == 1)
	{
		if (currentnumthreads >= numthreads)
		{
			return;
		}
		currentnumthreads++;
		func(-1);
		currentnumthreads--;
	} //end if
	else
	{
		ThreadLock();
		if (currentnumthreads >= numthreads)
		{
			ThreadUnlock();
			return;
		} //end if
		  //allocate new thread
		thread = GetMemory(sizeof(thread_t));
		if (!thread)
		{
			Error("can't allocate memory for thread\n");
		}

		//
		thread->threadid = currentthreadid;
		thread->handle   = CreateThread(
		    NULL,           // LPSECURITY_ATTRIBUTES lpsa,
		    0,              // DWORD cbStack,
		    (LPTHREAD_START_ROUTINE)func,           // LPTHREAD_START_ROUTINE lpStartAddr,
		    (LPVOID) thread->threadid,                  // LPVOID lpvThreadParm,
		    0,                              // DWORD fdwCreate,
		    &thread->id);

		//add the thread to the end of the list
		thread->next = NULL;
		if (lastthread)
		{
			lastthread->next = thread;
		}
		else
		{
			firstthread = thread;
		}
		lastthread = thread;
		//
#ifdef THREAD_DEBUG
		qprintf("added thread with id %d\n", thread->threadid);
#endif //THREAD_DEBUG
		//
		currentnumthreads++;
		currentthreadid++;
		//
		ThreadUnlock();
	} //end else
} //end of the function AddThread
Beispiel #6
0
/*
 * The main glob() routine: compiles the pattern (optionally processing
 * quotes), calls glob1() to do the real pattern matching, and finally
 * sorts the list (unless unsorted operation is requested).  Returns 0
 * if things went well, nonzero if errors occurred.  It is not an error
 * to find no matches.
 */
static int
glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
{
	const Char *qpatnext;
	int c, err, oldpathc;
	Char *bufnext, patbuf[PATH_MAX];

	qpatnext = globtilde(pattern, patbuf, PATH_MAX, pglob);
	oldpathc = pglob->gl_pathc;
	bufnext = patbuf;

	/* We don't need to check for buffer overflow any more. */
	while ((c = *qpatnext++) != EOS) {
		switch (c) {
		case LBRACKET:
			c = *qpatnext;
			if (c == NOT)
				++qpatnext;
			if (*qpatnext == EOS ||
			    g_strchr(qpatnext+1, RBRACKET) == NULL) {
				*bufnext++ = LBRACKET;
				if (c == NOT)
					--qpatnext;
				break;
			}
			*bufnext++ = M_SET;
			if (c == NOT)
				*bufnext++ = M_NOT;
			c = *qpatnext++;
			do {
				if (c == LBRACKET && *qpatnext == ':') {
					do {
						err = g_charclass(&qpatnext,
						    &bufnext);
						if (err)
							break;
						c = *qpatnext++;
					} while (c == LBRACKET && *qpatnext == ':');
					if (err == -1 &&
					    !(pglob->gl_flags & GLOB_NOCHECK))
						return GLOB_NOMATCH;
					if (c == RBRACKET)
						break;
				}
				*bufnext++ = CHAR(c);
				if (*qpatnext == RANGE &&
				    (c = qpatnext[1]) != RBRACKET) {
					*bufnext++ = M_RNG;
					*bufnext++ = CHAR(c);
					qpatnext += 2;
				}
			} while ((c = *qpatnext++) != RBRACKET);
			pglob->gl_flags |= GLOB_MAGCHAR;
			*bufnext++ = M_END;
			break;
		case QUESTION:
			pglob->gl_flags |= GLOB_MAGCHAR;
			*bufnext++ = M_ONE;
			break;
		case STAR:
			pglob->gl_flags |= GLOB_MAGCHAR;
			/* collapse adjacent stars to one,
			 * to avoid exponential behavior
			 */
			if (bufnext == patbuf || bufnext[-1] != M_ALL)
				*bufnext++ = M_ALL;
			break;
		default:
			*bufnext++ = CHAR(c);
			break;
		}
	}
	*bufnext = EOS;
#ifdef DEBUG
	qprintf("glob0:", patbuf);
#endif

	if ((err = glob1(patbuf, patbuf + PATH_MAX - 1, pglob, limitp)) != 0)
		return err;

	/*
	 * If there was no match we are going to append the pattern
	 * if GLOB_NOCHECK was specified.
	 */
	if (pglob->gl_pathc == oldpathc) {
		if ((pglob->gl_flags & GLOB_NOCHECK))
			return globextend(pattern, pglob, limitp, NULL);
		else
			return GLOB_NOMATCH;
	}
	if (!(pglob->gl_flags & GLOB_NOSORT)) {
		qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
		    pglob->gl_pathc - oldpathc, sizeof(char *), compare);
	}
	return 0;
}
Beispiel #7
0
//===========================================================================
// The incoming brush list will be freed before exiting
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
tree_t *BrushBSP( bspbrush_t *brushlist, vec3_t mins, vec3_t maxs ) {
	int i, c_faces, c_nonvisfaces, c_brushes;
	bspbrush_t *b;
	node_t *node;
	tree_t *tree;
	vec_t volume;
//	vec3_t point;

	Log_Print( "-------- Brush BSP ---------\n" );

	tree = Tree_Alloc();

	c_faces = 0;
	c_nonvisfaces = 0;
	c_brushes = 0;
	c_totalsides = 0;
	for ( b = brushlist; b; b = b->next )
	{
		c_brushes++;

		volume = BrushVolume( b );
		if ( volume < microvolume ) {
			Log_Print( "WARNING: entity %i, brush %i: microbrush\n",
					   b->original->entitynum, b->original->brushnum );
		} //end if

		for ( i = 0 ; i < b->numsides ; i++ )
		{
			if ( b->sides[i].flags & SFL_BEVEL ) {
				continue;
			}
			if ( !b->sides[i].winding ) {
				continue;
			}
			if ( b->sides[i].texinfo == TEXINFO_NODE ) {
				continue;
			}
			if ( b->sides[i].flags & SFL_VISIBLE ) {
				c_faces++;
			} //end if
			else
			{
				c_nonvisfaces++;
				//if (create_aas) b->sides[i].texinfo = TEXINFO_NODE;
			} //end if
		} //end for
		c_totalsides += b->numsides;

		AddPointToBounds( b->mins, tree->mins, tree->maxs );
		AddPointToBounds( b->maxs, tree->mins, tree->maxs );
	} //end for

	Log_Print( "%6i brushes\n", c_brushes );
	Log_Print( "%6i visible faces\n", c_faces );
	Log_Print( "%6i nonvisible faces\n", c_nonvisfaces );
	Log_Print( "%6i total sides\n", c_totalsides );

	c_active_brushes = c_brushes;
	c_nodememory = 0;
	c_brushmemory = 0;
	c_peak_brushmemory = 0;

	c_nodes = 0;
	c_nonvis = 0;
	node = AllocNode();

	//volume of first node (head node)
	node->volume = BrushFromBounds( mins, maxs );
	//
	tree->headnode = node;
	//just get some statistics and the mins/maxs of the node
	numrecurse = 0;
//	qprintf("%6d splits", numrecurse);

	tree->headnode->brushlist = brushlist;
	BuildTree( tree );

	//build the bsp tree with the start node from the brushlist
//	node = BuildTree_r(node, brushlist);

	//if the conversion is cancelled
	if ( cancelconversion ) {
		return tree;
	}

	qprintf( "\n" );
	Log_Write( "%6d splits\r\n", numrecurse );
//	Log_Print("%6i visible nodes\n", c_nodes/2 - c_nonvis);
//	Log_Print("%6i nonvis nodes\n", c_nonvis);
//	Log_Print("%6i leaves\n", (c_nodes+1)/2);
//	Log_Print("%6i solid leaf nodes\n", c_solidleafnodes);
//	Log_Print("%6i active brushes\n", c_active_brushes);
	if ( numthreads == 1 ) {
//		Log_Print("%6i KB of node memory\n", c_nodememory >> 10);
//		Log_Print("%6i KB of brush memory\n", c_brushmemory >> 10);
//		Log_Print("%6i KB of peak brush memory\n", c_peak_brushmemory >> 10);
//		Log_Print("%6i KB of winding memory\n", WindingMemory() >> 10);
//		Log_Print("%6i KB of peak winding memory\n", WindingPeakMemory() >> 10);
		Log_Print( "%6i KB of peak total bsp memory\n", c_peak_totalbspmemory >> 10 );
	} //end if
Beispiel #8
0
int
bsd_glob(const char *pattern, int flags,
	 int (*errfunc)(const char *, int), glob_t *pglob)
{
	const U8 *patnext;
	int c;
	Char *bufnext, *bufend, patbuf[MAXPATHLEN];

#ifdef MACOS_TRADITIONAL
	char *new_pat, *p, *np;
	int err;
	size_t len;
#endif

#ifndef MACOS_TRADITIONAL
	patnext = (U8 *) pattern;
#endif
	/* TODO: GLOB_APPEND / GLOB_DOOFFS aren't supported yet */
#if 0
	if (!(flags & GLOB_APPEND)) {
		pglob->gl_pathc = 0;
		pglob->gl_pathv = NULL;
		if (!(flags & GLOB_DOOFFS))
			pglob->gl_offs = 0;
	}
#else
	pglob->gl_pathc = 0;
	pglob->gl_pathv = NULL;
	pglob->gl_offs = 0;
#endif
	pglob->gl_flags = flags & ~GLOB_MAGCHAR;
	pglob->gl_errfunc = errfunc;
	pglob->gl_matchc = 0;

	bufnext = patbuf;
	bufend = bufnext + MAXPATHLEN - 1;
#ifdef DOSISH
	/* Nasty hack to treat patterns like "C:*" correctly. In this
	 * case, the * should match any file in the current directory
	 * on the C: drive. However, the glob code does not treat the
	 * colon specially, so it looks for files beginning "C:" in
	 * the current directory. To fix this, change the pattern to
	 * add an explicit "./" at the start (just after the drive
	 * letter and colon - ie change to "C:./").
	 */
	if (isalpha(pattern[0]) && pattern[1] == ':' &&
	    pattern[2] != BG_SEP && pattern[2] != BG_SEP2 &&
	    bufend - bufnext > 4) {
		*bufnext++ = pattern[0];
		*bufnext++ = ':';
		*bufnext++ = '.';
		*bufnext++ = BG_SEP;
		patnext += 2;
	}
#endif

#ifdef MACOS_TRADITIONAL
	/* Check if we need to match a volume name (e.g. '*HD:*') */
	g_matchVol = false;
	p = (char *) pattern;
	if (*p != BG_SEP) {
	    p++;
	    while (*p != BG_EOS) {
		if (*p == BG_SEP) {
		    g_matchVol = true;
		    break;
		}
		p++;
	    }
	}

	/* Transform the pattern:
	 * (a) Resolve updirs, e.g.
	 *     '*:t*p::'       -> '*:'
	 *	   ':a*:tmp::::'   -> '::'
	 *	   ':base::t*p:::' -> '::'
	 *     '*HD::'         -> return 0 (error, quit silently)
	 *
	 * (b) Remove a single trailing ':', unless it's a "match volume only"
	 *     pattern like '*HD:'; e.g.
	 *     '*:tmp:' -> '*:tmp'  but
	 *     '*HD:'   -> '*HD:'
	 *     (If we don't do that, even filenames will have a trailing ':' in
	 *     the result.)
	 */

	/* We operate on a copy of the pattern */
	len = strlen(pattern);
	Newx(new_pat, len + 1, char);
	if (new_pat == NULL)
	    return (GLOB_NOSPACE);

	p = (char *) pattern;
	np = new_pat;
	while (*np++ = *p++) ;

	/* Resolve updirs ... */
	err = resolve_updirs(new_pat);
	if (err) {
	    Safefree(new_pat);
	    /* The pattern is incorrect: tried to move
	       up above the volume root, see above.
	       We quit silently. */
	    return 0;
	}
	/* remove trailing colon ... */
	remove_trColon(new_pat);
	patnext = (U8 *) new_pat;

#endif /* MACOS_TRADITIONAL */

	if (flags & GLOB_QUOTE) {
		/* Protect the quoted characters. */
		while (bufnext < bufend && (c = *patnext++) != BG_EOS)
			if (c == BG_QUOTE) {
#ifdef DOSISH
				    /* To avoid backslashitis on Win32,
				     * we only treat \ as a quoting character
				     * if it precedes one of the
				     * metacharacters []-{}~\
				     */
				if ((c = *patnext++) != '[' && c != ']' &&
				    c != '-' && c != '{' && c != '}' &&
				    c != '~' && c != '\\') {
#else
				if ((c = *patnext++) == BG_EOS) {
#endif
					c = BG_QUOTE;
					--patnext;
				}
				*bufnext++ = c | M_PROTECT;
			} else
				*bufnext++ = c;
	} else
		while (bufnext < bufend && (c = *patnext++) != BG_EOS)
			*bufnext++ = c;
	*bufnext = BG_EOS;

#ifdef MACOS_TRADITIONAL
	if (flags & GLOB_BRACE)
	    err = globexp1(patbuf, pglob);
	else
	    err = glob0(patbuf, pglob);
	Safefree(new_pat);
	return err;
#else
	if (flags & GLOB_BRACE)
	    return globexp1(patbuf, pglob);
	else
	    return glob0(patbuf, pglob);
#endif
}

/*
 * Expand recursively a glob {} pattern. When there is no more expansion
 * invoke the standard globbing routine to glob the rest of the magic
 * characters
 */
static int
globexp1(const Char *pattern, glob_t *pglob)
{
	const Char* ptr = pattern;
	int rv;

	/* Protect a single {}, for find(1), like csh */
	if (pattern[0] == BG_LBRACE && pattern[1] == BG_RBRACE && pattern[2] == BG_EOS)
		return glob0(pattern, pglob);

	while ((ptr = (const Char *) g_strchr((Char *) ptr, BG_LBRACE)) != NULL)
		if (!globexp2(ptr, pattern, pglob, &rv))
			return rv;

	return glob0(pattern, pglob);
}


/*
 * Recursive brace globbing helper. Tries to expand a single brace.
 * If it succeeds then it invokes globexp1 with the new pattern.
 * If it fails then it tries to glob the rest of the pattern and returns.
 */
static int
globexp2(const Char *ptr, const Char *pattern,
	 glob_t *pglob, int *rv)
{
	int     i;
	Char   *lm, *ls;
	const Char *pe, *pm, *pl;
	Char    patbuf[MAXPATHLEN];

	/* copy part up to the brace */
	for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
		;
	*lm = BG_EOS;
	ls = lm;

	/* Find the balanced brace */
	for (i = 0, pe = ++ptr; *pe; pe++)
		if (*pe == BG_LBRACKET) {
			/* Ignore everything between [] */
			for (pm = pe++; *pe != BG_RBRACKET && *pe != BG_EOS; pe++)
				;
			if (*pe == BG_EOS) {
				/*
				 * We could not find a matching BG_RBRACKET.
				 * Ignore and just look for BG_RBRACE
				 */
				pe = pm;
			}
		} else if (*pe == BG_LBRACE)
			i++;
		else if (*pe == BG_RBRACE) {
			if (i == 0)
				break;
			i--;
		}

	/* Non matching braces; just glob the pattern */
	if (i != 0 || *pe == BG_EOS) {
		*rv = glob0(patbuf, pglob);
		return 0;
	}

	for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
		switch (*pm) {
		case BG_LBRACKET:
			/* Ignore everything between [] */
			for (pl = pm++; *pm != BG_RBRACKET && *pm != BG_EOS; pm++)
				;
			if (*pm == BG_EOS) {
				/*
				 * We could not find a matching BG_RBRACKET.
				 * Ignore and just look for BG_RBRACE
				 */
				pm = pl;
			}
			break;

		case BG_LBRACE:
			i++;
			break;

		case BG_RBRACE:
			if (i) {
				i--;
				break;
			}
			/* FALLTHROUGH */
		case BG_COMMA:
			if (i && *pm == BG_COMMA)
				break;
			else {
				/* Append the current string */
				for (lm = ls; (pl < pm); *lm++ = *pl++)
					;

				/*
				 * Append the rest of the pattern after the
				 * closing brace
				 */
				for (pl = pe + 1; (*lm++ = *pl++) != BG_EOS; )
					;

				/* Expand the current pattern */
#ifdef GLOB_DEBUG
				qprintf("globexp2:", patbuf);
#endif /* GLOB_DEBUG */
				*rv = globexp1(patbuf, pglob);

				/* move after the comma, to the next string */
				pl = pm + 1;
			}
			break;

		default:
			break;
		}
	}
	*rv = 0;
	return 0;
}
Beispiel #9
0
/*
 * The main glob() routine: compiles the pattern (optionally processing
 * quotes), calls glob1() to do the real pattern matching, and finally
 * sorts the list (unless unsorted operation is requested).  Returns 0
 * if things went well, nonzero if errors occurred.  It is not an error
 * to find no matches.
 */
static int
glob0(const Char *pattern, glob_t *pglob)
{
	const Char *qpat, *qpatnext;
	int c, err, oldflags, oldpathc;
	Char *bufnext, patbuf[MAXPATHLEN];
	size_t limit = 0;

#ifdef MACOS_TRADITIONAL
	if ( (*pattern == BG_TILDE) && (pglob->gl_flags & GLOB_TILDE) ) {
		return(globextend(pattern, pglob, &limit));
	}
#endif

	qpat = globtilde(pattern, patbuf, MAXPATHLEN, pglob);
	qpatnext = qpat;
	oldflags = pglob->gl_flags;
	oldpathc = pglob->gl_pathc;
	bufnext = patbuf;

	/* We don't need to check for buffer overflow any more. */
	while ((c = *qpatnext++) != BG_EOS) {
		switch (c) {
		case BG_LBRACKET:
			c = *qpatnext;
			if (c == BG_NOT)
				++qpatnext;
			if (*qpatnext == BG_EOS ||
			    g_strchr((Char *) qpatnext+1, BG_RBRACKET) == NULL) {
				*bufnext++ = BG_LBRACKET;
				if (c == BG_NOT)
					--qpatnext;
				break;
			}
			*bufnext++ = M_SET;
			if (c == BG_NOT)
				*bufnext++ = M_NOT;
			c = *qpatnext++;
			do {
				*bufnext++ = CHAR(c);
				if (*qpatnext == BG_RANGE &&
				    (c = qpatnext[1]) != BG_RBRACKET) {
					*bufnext++ = M_RNG;
					*bufnext++ = CHAR(c);
					qpatnext += 2;
				}
			} while ((c = *qpatnext++) != BG_RBRACKET);
			pglob->gl_flags |= GLOB_MAGCHAR;
			*bufnext++ = M_END;
			break;
		case BG_QUESTION:
			pglob->gl_flags |= GLOB_MAGCHAR;
			*bufnext++ = M_ONE;
			break;
		case BG_STAR:
			pglob->gl_flags |= GLOB_MAGCHAR;
			/* collapse adjacent stars to one,
			 * to avoid exponential behavior
			 */
			if (bufnext == patbuf || bufnext[-1] != M_ALL)
				*bufnext++ = M_ALL;
			break;
		default:
			*bufnext++ = CHAR(c);
			break;
		}
	}
	*bufnext = BG_EOS;
#ifdef GLOB_DEBUG
	qprintf("glob0:", patbuf);
#endif /* GLOB_DEBUG */

	if ((err = glob1(patbuf, patbuf+MAXPATHLEN-1, pglob, &limit)) != 0) {
		pglob->gl_flags = oldflags;
		return(err);
	}

	/*
	 * If there was no match we are going to append the pattern
	 * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
	 * and the pattern did not contain any magic characters
	 * GLOB_NOMAGIC is there just for compatibility with csh.
	 */
	if (pglob->gl_pathc == oldpathc &&
	    ((pglob->gl_flags & GLOB_NOCHECK) ||
	      ((pglob->gl_flags & GLOB_NOMAGIC) &&
	       !(pglob->gl_flags & GLOB_MAGCHAR))))
	{
#ifdef GLOB_DEBUG
		printf("calling globextend from glob0\n");
#endif /* GLOB_DEBUG */
		pglob->gl_flags = oldflags;
		return(globextend(qpat, pglob, &limit));
        }
	else if (!(pglob->gl_flags & GLOB_NOSORT))
		qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
		    pglob->gl_pathc - oldpathc, sizeof(char *),
		    (pglob->gl_flags & (GLOB_ALPHASORT|GLOB_NOCASE))
			? ci_compare : compare);
	pglob->gl_flags = oldflags;
	return(0);
}
Beispiel #10
0
int main (int argc, char **argv)
{
	int		i, j;
	int		hull;
	entity_t	*ent;
	char	source[1024];
	char	name[1024];
	double		start, end;

	printf( "qcsg.exe v2.8 (%s)\n", __DATE__ );
	printf ("---- qcsg ----\n" );

	for (i=1 ; i<argc ; i++)
	{
		if (!strcmp(argv[i],"-threads"))
		{
			numthreads = atoi (argv[i+1]);
			i++;
		}
		else if (!strcmp(argv[i],"-glview"))
		{
			glview = true;
		}
		else if (!strcmp(argv[i], "-v"))
		{
			printf ("verbose = true\n");
			verbose = true;
		}
		else if (!strcmp(argv[i], "-draw"))
		{
			printf ("drawflag = true\n");
			drawflag = true;
		}
		else if (!strcmp(argv[i], "-noclip"))
		{
			printf ("noclip = true\n");
			noclip = true;
		}
		else if (!strcmp(argv[i], "-onlyents"))
		{
			printf ("onlyents = true\n");
			onlyents = true;
		}
		else if (!strcmp(argv[i], "-nowadtextures"))
		{
			printf ("wadtextures = false\n");
			wadtextures = false;
		}
		else if (!strcmp(argv[i], "-wadinclude"))
		{
			pszWadInclude[nWadInclude++] = strdup( argv[i + 1] );
			i++;
		}
		else if( !strcmp( argv[ i ], "-proj" ) )
		{
			strcpy( qproject, argv[ i + 1 ] );
			i++;
		}
		else if (!strcmp(argv[i], "-hullfile"))
		{
			hullfile = true;
			strcpy( qhullfile, argv[i + 1] );
			i++;
		}
		else if (argv[i][0] == '-')
			Error ("Unknown option \"%s\"", argv[i]);
		else
			break;
	}

	if (i != argc - 1)
		Error ("usage: qcsg [-nowadtextures] [-wadinclude <name>] [-draw] [-glview] [-noclip] [-onlyents] [-proj <name>] [-threads #] [-v] [-hullfile <name>] mapfile");

	SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
	start = I_FloatTime ();

	CheckHullFile( hullfile, qhullfile );

	ThreadSetDefault ();
	SetQdirFromPath (argv[i]);

	strcpy (source, ExpandArg (argv[i]));
	COM_FixSlashes(source);
	StripExtension (source);

	strcpy (name, ExpandArg (argv[i]));	
	DefaultExtension (name, ".map");	// might be .reg

	//
	// if onlyents, just grab the entites and resave
	//
	if (onlyents  && !glview)
	{
		char out[1024];
		int	old_entities;
		sprintf (out, "%s.bsp", source);
		LoadBSPFile (out);

		// Get the new entity data from the map file
		LoadMapFile (name);

		// Write it all back out again.
		WriteBSP (source);

		end = I_FloatTime ();
		printf ("%5.0f seconds elapsed\n", end-start);
		return 0;
	}

	//
	// start from scratch
	//
	LoadMapFile (name);

	RunThreadsOnIndividual (nummapbrushes, true, CreateBrush);

	BoundWorld ();

	qprintf ("%5i map planes\n", nummapplanes);

	for (i=0 ; i<NUM_HULLS ; i++)
	{
		char	name[1024];

		if (glview)
			sprintf (name, "%s.gl%i",source, i);
		else
			sprintf (name, "%s.p%i",source, i);
		out[i] = fopen (name, "w");
		if (!out[i])
			Error ("Couldn't open %s",name);
	}

	ProcessModels ();

	qprintf ("%5i csg faces\n", c_csgfaces);
	qprintf ("%5i used faces\n", c_outfaces);
	qprintf ("%5i tiny faces\n", c_tiny);
	qprintf ("%5i tiny clips\n", c_tiny_clip);

	for (i=0 ; i<NUM_HULLS ; i++)
		fclose (out[i]);

	if (!glview)
	{
		EmitPlanes ();
		WriteBSP (source);
	}

	end = I_FloatTime ();
	printf ("%5.0f seconds elapsed\n", end-start);

	return 0;
}
Beispiel #11
0
/*
===============
ProcessEntity
===============
*/
static void ProcessEntity (int entnum)
{
    entity_t	*ent;
    char	mod[80];
    surface_t	*surfs;
    node_t		*nodes;
    brushset_t	*bs;

    ent = &entities[entnum];
    if (!ent->brushes)
        return;		// non-bmodel entity

    if (entnum > 0)
    {
        worldmodel = false;
        if (entnum == 1)
            qprintf ("--- Internal Entities ---\n");
        sprintf (mod, "*%i", nummodels);
        if (verbose)
            PrintEntity (ent);

        if (hullnum == 0)
            printf ("MODEL: %s\n", mod);
        SetKeyValue (ent, "model", mod);
    }
    else
        worldmodel = true;

//
// take the brush_ts and clip off all overlapping and contained faces,
// leaving a perfect skin of the model with no hidden faces
//
    bs = Brush_LoadEntity (ent, hullnum);

    if (!bs->brushes)
    {
        PrintEntity (ent);
        Error ("Entity with no valid brushes");
    }

    brushset = bs;
    surfs = CSGFaces (bs);

    if (hullnum != 0)
    {
        nodes = SolidBSP (surfs, true);
        if (entnum == 0 && !nofill)	// assume non-world bmodels are simple
        {
            PortalizeWorld (nodes);
            if (FillOutside (nodes))
            {
                surfs = GatherNodeFaces (nodes);
                nodes = SolidBSP (surfs, false);	// make a really good tree
            }
            FreeAllPortals (nodes);
        }
        WriteNodePlanes (nodes);
        WriteClipNodes (nodes);
        BumpModel (hullnum);
    }
    else
    {
        //
        // SolidBSP generates a node tree
        //
        // if not the world, make a good tree first
        // the world is just going to make a bad tree
        // because the outside filling will force a regeneration later
        nodes = SolidBSP (surfs, entnum == 0);

        //
        // build all the portals in the bsp tree
        // some portals are solid polygons, and some are paths to other leafs
        //
        if (entnum == 0 && !nofill)	// assume non-world bmodels are simple
        {
            PortalizeWorld (nodes);

            if (FillOutside (nodes))
            {
                FreeAllPortals (nodes);

                // get the remaining faces together into surfaces again
                surfs = GatherNodeFaces (nodes);

                // merge polygons
                MergeAll (surfs);

                // make a really good tree
                nodes = SolidBSP (surfs, false);

                // make the real portals for vis tracing
                PortalizeWorld (nodes);

                // save portal file for vis tracing
                WritePortalfile (nodes);

                // fix tjunctions
                tjunc (nodes);
            }
            FreeAllPortals (nodes);
        }

        WriteNodePlanes (nodes);
        MakeFaceEdges (nodes);
        WriteDrawNodes (nodes);
    }
}
Beispiel #12
0
/*
===========
CSGBrush
===========
*/
void CSGBrush (int brushnum)
{
	int			hull;
	brush_t		*b1, *b2;
	brushhull_t	*bh1, *bh2;
	int			bn;
	qboolean	overwrite;
	int			i;
	bface_t		*f, *f2, *next, *fcopy;
	bface_t		*outside, *oldoutside;
	entity_t	*e;
	vec_t		area;

	SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);

	b1 = &mapbrushes[brushnum];

	e = &entities[b1->entitynum];

	for (hull = 0 ; hull<NUM_HULLS ; hull++)
	{
		bh1 = &b1->hulls[hull];

		// set outside to a copy of the brush's faces
		outside = CopyFacesToOutside (bh1);
		overwrite = false;

		for (bn=0 ; bn<e->numbrushes ; bn++)
		{
			// see if b2 needs to clip a chunk out of b1

			if (bn==brushnum)
			{
				overwrite = true;	// later brushes now overwrite
				continue;
			}

			b2 = &mapbrushes[e->firstbrush + bn];
			bh2 = &b2->hulls[hull];

			if (!bh2->faces)
				continue;		// brush isn't in this hull

			// check brush bounding box first
			for (i=0 ; i<3 ; i++)
				if (bh1->mins[i] > bh2->maxs[i] 
				|| bh1->maxs[i] < bh2->mins[i])
					break;
			if (i<3)
				continue;

			// divide faces by the planes of the b2 to find which
			// fragments are inside
		
			f = outside;
			outside = NULL;
			for ( ; f ; f=next)
			{
				next = f->next;

				// check face bounding box first
				for (i=0 ; i<3 ; i++)
					if (bh2->mins[i] > f->maxs[i] 
					|| bh2->maxs[i] < f->mins[i])
						break;
				if (i<3)
				{	// this face doesn't intersect brush2's bbox
					f->next = outside;
					outside = f;
					continue;
				}

				oldoutside = outside;
				fcopy = CopyFace (f);	// save to avoid fake splits

				// throw pieces on the front sides of the planes
				// into the outside list, return the remains on the inside
				for (f2=bh2->faces ; f2 && f ; f2=f2->next)
					f = ClipFace (b1, f, &outside, f2->planenum, overwrite);

				area = f ? WindingArea (f->w) : 0;
				if (f && area < 1.0)
				{
					qprintf ("Entity %i, Brush %i: tiny penetration\n"
						, b1->entitynum, b1->brushnum);
					c_tiny_clip++;
					FreeFace (f);
					f = NULL;
				}
				if (f)
				{
					// there is one convex fragment of the original
					// face left inside brush2
					FreeFace (fcopy);

					if (b1->contents > b2->contents)
					{	// inside a water brush
						f->contents = b2->contents;
						f->next = outside;
						outside = f;
					}
					else	// inside a solid brush
						FreeFace (f);	// throw it away
				}
				else
				{	// the entire thing was on the outside, even
					// though the bounding boxes intersected,
					// which will never happen with axial planes

					// free the fragments chopped to the outside
					while (outside != oldoutside)
					{
						f2 = outside->next;
						FreeFace (outside);
						outside = f2;
					}

					// revert to the original face to avoid
					// unneeded false cuts
					fcopy->next = outside;
					outside = fcopy;
				}
			}

		}

		// all of the faces left in outside are real surface faces
		SaveOutside (b1, hull, outside, b1->contents);
	}
}
Beispiel #13
0
static int parse_proc_stat(void)
{
    int age;

    /* reread every 10 msec only */
    age = hash_age(&Stat, NULL);
    if (age > 0 && age <= 10)
	return 0;

#ifndef __MAC_OS_X_VERSION_10_3

    /* Linux Kernel, /proc-filesystem */

    if (stream == NULL)
	stream = fopen("/proc/stat", "r");
    if (stream == NULL) {
	error("fopen(/proc/stat) failed: %s", strerror(errno));
	return -1;
    }

    rewind(stream);

    while (!feof(stream)) {
	char buffer[1024];
	if (fgets(buffer, sizeof(buffer), stream) == NULL)
	    break;

	if (strncmp(buffer, "cpu", 3) == 0) {
	    char *key[] = { "user", "nice", "system", "idle", "iow", "irq", "sirq" };
	    char delim[] = " \t\n";
	    char *cpu, *beg, *end;
	    int i;

	    cpu = buffer;

	    /* skip "cpu" or "cpu0" block */
	    if ((end = strpbrk(buffer, delim)) != NULL)
		*end = '\0';
	    beg = end ? end + 1 : NULL;

	    for (i = 0; i < 7 && beg != NULL; i++) {
		while (strchr(delim, *beg))
		    beg++;
		if ((end = strpbrk(beg, delim)))
		    *end = '\0';
		hash_put2(cpu, key[i], beg);
		beg = end ? end + 1 : NULL;
	    }
	}

	else if (strncmp(buffer, "page ", 5) == 0) {
	    char *key[] = { "in", "out" };
	    char delim[] = " \t\n";
	    char *beg, *end;
	    int i;

	    for (i = 0, beg = buffer + 5; i < 2 && beg != NULL; i++) {
		while (strchr(delim, *beg))
		    beg++;
		if ((end = strpbrk(beg, delim)))
		    *end = '\0';
		hash_put2("page", key[i], beg);
		beg = end ? end + 1 : NULL;
	    }
	}

	else if (strncmp(buffer, "swap ", 5) == 0) {
	    char *key[] = { "in", "out" };
	    char delim[] = " \t\n";
	    char *beg, *end;
	    int i;

	    for (i = 0, beg = buffer + 5; i < 2 && beg != NULL; i++) {
		while (strchr(delim, *beg))
		    beg++;
		if ((end = strpbrk(beg, delim)))
		    *end = '\0';
		hash_put2("swap", key[i], beg);
		beg = end ? end + 1 : NULL;
	    }
	}

	else if (strncmp(buffer, "intr ", 5) == 0) {
	    char delim[] = " \t\n";
	    char *beg, *end, num[4];
	    int i;

	    for (i = 0, beg = buffer + 5; i < 17 && beg != NULL; i++) {
		while (strchr(delim, *beg))
		    beg++;
		if ((end = strpbrk(beg, delim)))
		    *end = '\0';
		if (i == 0)
		    strcpy(num, "sum");
		else
		    qprintf(num, sizeof(num), "%d", i - 1);
		hash_put2("intr", num, beg);
		beg = end ? end + 1 : NULL;
	    }
	}

	else if (strncmp(buffer, "disk_io:", 8) == 0) {
	    char *key[] = { "io", "rio", "rblk", "wio", "wblk" };
	    char delim[] = " ():,\t\n";
	    char *dev, *beg, *end, *p;
	    int i;

	    dev = buffer + 8;
	    while (dev != NULL) {
		while (strchr(delim, *dev))
		    dev++;
		if ((end = strchr(dev, ')')))
		    *end = '\0';
		while ((p = strchr(dev, ',')) != NULL)
		    *p = ':';
		beg = end ? end + 1 : NULL;
		for (i = 0; i < 5 && beg != NULL; i++) {
		    while (strchr(delim, *beg))
			beg++;
		    if ((end = strpbrk(beg, delim)))
			*end = '\0';
		    hash_put3("disk_io", dev, key[i], beg);
		    beg = end ? end + 1 : NULL;
		}
		dev = beg;
	    }
	}

	else {
	    char delim[] = " \t\n";
	    char *beg, *end;

	    beg = buffer;
	    if ((end = strpbrk(beg, delim)))
		*end = '\0';
	    beg = end ? end + 1 : NULL;
	    if ((end = strpbrk(beg, delim)))
		*end = '\0';
	    while (strchr(delim, *beg))
		beg++;
	    hash_put1(buffer, beg);
	}
    }

#else

    /* MACH Kernel, MacOS X */

    kern_return_t err;
    mach_msg_type_number_t count;
    host_info_t r_load;
    host_cpu_load_info_data_t cpu_load;
    char s_val[8];

    r_load = &cpu_load;
    count = HOST_CPU_LOAD_INFO_COUNT;
    err = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, r_load, &count);
    if (KERN_SUCCESS != err) {
	error("Error getting cpu load");
	return -1;
    }
    snprintf(s_val, sizeof(s_val), "%d", cpu_load.cpu_ticks[CPU_STATE_USER]);
    hash_put2("cpu", "user", s_val);
    snprintf(s_val, sizeof(s_val), "%d", cpu_load.cpu_ticks[CPU_STATE_NICE]);
    hash_put2("cpu", "nice", s_val);
    snprintf(s_val, sizeof(s_val), "%d", cpu_load.cpu_ticks[CPU_STATE_SYSTEM]);
    hash_put2("cpu", "system", s_val);
    snprintf(s_val, sizeof(s_val), "%d", cpu_load.cpu_ticks[CPU_STATE_IDLE]);
    hash_put2("cpu", "idle", s_val);

#endif

    return 0;
}
Beispiel #14
0
static int				/* O - 0 on success, -1 on error */
write_spec(int        format,		/* I - Subformat */
           const char *prodname,	/* I - Product name */
	   dist_t     *dist,		/* I - Distribution */
           FILE       *fp,		/* I - Spec file */
           const char *subpackage)	/* I - Subpackage name */
{
  int		i;			/* Looping var */
  char		name[1024];		/* Full product name */
  const char	*product;		/* Product to depend on */
  file_t	*file;			/* Current distribution file */
  command_t	*c;			/* Current command */
  depend_t	*d;			/* Current dependency */
  const char	*runlevels;		/* Run levels */
  int		number;			/* Start/stop number */
  int		have_commands;		/* Have commands in current section? */


 /*
  * Get the name we'll use for the subpackage...
  */

  if (subpackage)
    snprintf(name, sizeof(name), " %s", subpackage);
  else
    name[0] = '\0';

 /*
  * Common stuff...
  */

  if (subpackage)
  {
    fprintf(fp, "%%package%s\n", name);
    fprintf(fp, "Summary: %s", dist->product);

    for (i = 0; i < dist->num_descriptions; i ++)
      if (dist->descriptions[i].subpackage == subpackage)
	break;

    if (i < dist->num_descriptions)
    {
      char	line[1024],		/* First line of description... */
		*ptr;			/* Pointer into line */


      strlcpy(line, dist->descriptions[i].description, sizeof(line));
      if ((ptr = strchr(line, '\n')) != NULL)
        *ptr = '\0';

      fprintf(fp, " - %s", line);
    }
    fputs("\n", fp);
  }
  else
    fprintf(fp, "Summary: %s\n", dist->product);

  fputs("Group: Applications\n", fp);

 /*
  * List all of the dependencies...
  */

  for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++)
  {
    if (d->subpackage != subpackage)
      continue;

    if (!strcmp(d->product, "_self"))
      product = prodname;
    else
      product = d->product;

    if (d->type == DEPEND_REQUIRES)
      fprintf(fp, "Requires: %s", product);
    else if (d->type == DEPEND_PROVIDES)
      fprintf(fp, "Provides: %s", product);
    else if (d->type == DEPEND_REPLACES)
      fprintf(fp, "Obsoletes: %s", product);
    else
      fprintf(fp, "Conflicts: %s", product);

    if (d->vernumber[0] == 0)
    {
      if (d->vernumber[1] < INT_MAX)
        fprintf(fp, " <= %s\n", d->version[1]);
      else
        putc('\n', fp);
    }
    else if (d->vernumber[0] && d->vernumber[1] < INT_MAX)
    {
      if (d->vernumber[0] < INT_MAX && d->vernumber[1] < INT_MAX)
        fprintf(fp, " >= %s, %s <= %s\n", d->version[0], product,
	        d->version[1]);
    }
    else if (d->vernumber[0] != d->vernumber[1])
      fprintf(fp, " >= %s\n", d->version[0]);
    else
      fprintf(fp, " = %s\n", d->version[0]);
  }

 /*
  * Pre/post install commands...
  */

  for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
    if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage)
      break;

  if (i > 0)
  {
    fprintf(fp, "%%pre%s\n", name);
    for (; i > 0; i --, c ++)
      if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage)
	fprintf(fp, "%s\n", c->command);
  }

  for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
    if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage)
      break;

  if (i > 0)
  {
    have_commands = 1;

    fprintf(fp, "%%post%s\n", name);
    for (; i > 0; i --, c ++)
      if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage)
	fprintf(fp, "%s\n", c->command);

  }
  else
    have_commands = 0;

  for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
    if (c->type == COMMAND_LITERAL && c->subpackage == subpackage &&
        !strcmp(c->section, "spec"))
      break;

  if (i > 0)
  {
    for (; i > 0; i --, c ++)
      if (c->type == COMMAND_LITERAL && c->subpackage == subpackage &&
	  !strcmp(c->section, "spec"))
	fprintf(fp, "%s\n", c->command);
  }

  for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
    if (tolower(file->type) == 'i' && file->subpackage == subpackage)
      break;

  if (i)
  {
    if (!have_commands)
      fprintf(fp, "%%post%s\n", name);

    fputs("if test \"x$1\" = x1; then\n", fp);
    fputs("	echo Setting up init scripts...\n", fp);

    if (format == PACKAGE_LSB)
    {
     /*
      * Use LSB commands to install the init scripts...
      */

      for (; i > 0; i --, file ++)
	if (tolower(file->type) == 'i' && file->subpackage == subpackage)
	{
	  fprintf(fp, "	/usr/lib/lsb/install_initd /etc/init.d/%s\n", file->dst);
	  fprintf(fp, "	/etc/init.d/%s start\n", file->dst);
	}
    }
    else
    {
     /*
      * Find where the frigging init scripts go...
      */

      fputs("	rcdir=\"\"\n", fp);
      fputs("	for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", fp);
      fputs("		if test -d $dir/rc3.d -o -h $dir/rc3.d; then\n", fp);
      fputs("			rcdir=\"$dir\"\n", fp);
      fputs("		fi\n", fp);
      fputs("	done\n", fp);
      fputs("	if test \"$rcdir\" = \"\" ; then\n", fp);
      fputs("		echo Unable to determine location of startup scripts!\n", fp);
      fputs("	else\n", fp);
      for (; i > 0; i --, file ++)
	if (tolower(file->type) == 'i' && file->subpackage == subpackage)
	{
	  fputs("		if test -d $rcdir/init.d; then\n", fp);
	  qprintf(fp, "			/bin/rm -f $rcdir/init.d/%s\n", file->dst);
	  qprintf(fp, "			/bin/ln -s %s/init.d/%s "
		      "$rcdir/init.d/%s\n", SoftwareDir, file->dst, file->dst);
	  fputs("		else\n", fp);
	  fputs("			if test -d /etc/init.d; then\n", fp);
	  qprintf(fp, "				/bin/rm -f /etc/init.d/%s\n", file->dst);
	  qprintf(fp, "				/bin/ln -s %s/init.d/%s "
		      "/etc/init.d/%s\n", SoftwareDir, file->dst, file->dst);
	  fputs("			fi\n", fp);
	  fputs("		fi\n", fp);

	  for (runlevels = get_runlevels(dist->files + i, "0123456");
	       isdigit(*runlevels & 255);
	       runlevels ++)
	  {
	    if (*runlevels == '0')
	      number = get_stop(file, 0);
	    else
	      number = get_start(file, 99);

	    qprintf(fp, "		/bin/rm -f $rcdir/rc%c.d/%c%02d%s\n", *runlevels,
		    (*runlevels == '0' || *runlevels == '1' ||
		     *runlevels == '6') ? 'K' : 'S', number, file->dst);
	    qprintf(fp, "		/bin/ln -s %s/init.d/%s "
			"$rcdir/rc%c.d/%c%02d%s\n", SoftwareDir, file->dst,
		    *runlevels,
		    (*runlevels == '0' || *runlevels == '1' ||
		     *runlevels == '6') ? 'K' : 'S', number, file->dst);
	  }

	  qprintf(fp, "		%s/init.d/%s start\n", SoftwareDir, file->dst);
	}

      fputs("	fi\n", fp);
    }

    fputs("fi\n", fp);
  }

  for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
    if (tolower(file->type) == 'i' && file->subpackage == subpackage)
      break;

  if (i)
  {
    have_commands = 1;

    fprintf(fp, "%%preun%s\n", name);
    fputs("if test \"x$1\" = x0; then\n", fp);
    fputs("	echo Cleaning up init scripts...\n", fp);

    if (format == PACKAGE_LSB)
    {
     /*
      * Use LSB commands to remove the init scripts...
      */

      for (; i > 0; i --, file ++)
	if (tolower(file->type) == 'i' && file->subpackage == subpackage)
	{
	  fprintf(fp, "	/etc/init.d/%s stop\n", file->dst);
	  fprintf(fp, "	/usr/lib/lsb/remove_initd /etc/init.d/%s\n", file->dst);
	}
    }
    else
    {
     /*
      * Find where the frigging init scripts go...
      */

      fputs("	rcdir=\"\"\n", fp);
      fputs("	for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", fp);
      fputs("		if test -d $dir/rc3.d -o -h $dir/rc3.d; then\n", fp);
      fputs("			rcdir=\"$dir\"\n", fp);
      fputs("		fi\n", fp);
      fputs("	done\n", fp);
      fputs("	if test \"$rcdir\" = \"\" ; then\n", fp);
      fputs("		echo Unable to determine location of startup scripts!\n", fp);
      fputs("	else\n", fp);
      for (; i > 0; i --, file ++)
	if (tolower(file->type) == 'i' && file->subpackage == subpackage)
	{
	  qprintf(fp, "		%s/init.d/%s stop\n", SoftwareDir, file->dst);

	  fputs("		if test -d $rcdir/init.d; then\n", fp);
	  qprintf(fp, "			/bin/rm -f $rcdir/init.d/%s\n", file->dst);
	  fputs("		else\n", fp);
	  fputs("			if test -d /etc/init.d; then\n", fp);
	  qprintf(fp, "				/bin/rm -f /etc/init.d/%s\n", file->dst);
	  fputs("			fi\n", fp);
	  fputs("		fi\n", fp);

	  for (runlevels = get_runlevels(dist->files + i, "0123456");
	       isdigit(*runlevels & 255);
	       runlevels ++)
	  {
	    if (*runlevels == '0')
	      number = get_stop(file, 0);
	    else
	      number = get_start(file, 99);

	    qprintf(fp, "		/bin/rm -f $rcdir/rc%c.d/%c%02d%s\n", *runlevels,
		    (*runlevels == '0' || *runlevels == '1' ||
		     *runlevels == '6') ? 'K' : 'S', number, file->dst);
	  }
	}

      fputs("	fi\n", fp);
    }

    fputs("fi\n", fp);
  }
  else
    have_commands = 0;

  for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
    if (c->type == COMMAND_PRE_REMOVE && c->subpackage == subpackage)
      break;

  if (i > 0)
  {
    if (!have_commands)
      fprintf(fp, "%%preun%s\n", name);

    for (; i > 0; i --, c ++)
      if (c->type == COMMAND_PRE_REMOVE && c->subpackage == subpackage)
	fprintf(fp, "%s\n", c->command);
  }

  for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
    if (c->type == COMMAND_POST_REMOVE && c->subpackage == subpackage)
      break;

  if (i > 0)
  {
    fprintf(fp, "%%postun%s\n", name);
    for (; i > 0; i --, c ++)
      if (c->type == COMMAND_POST_REMOVE && c->subpackage == subpackage)
	fprintf(fp, "%s\n", c->command);
  }

 /*
  * Description...
  */

  for (i = 0; i < dist->num_descriptions; i ++)
    if (dist->descriptions[i].subpackage == subpackage)
      break;

  if (i < dist->num_descriptions)
  {
    fprintf(fp, "%%description %s\n", name);

    for (; i < dist->num_descriptions; i ++)
      if (dist->descriptions[i].subpackage == subpackage)
	fprintf(fp, "%s\n", dist->descriptions[i].description);
  }

 /*
  * Files...
  */

  fprintf(fp, "%%files%s\n", name);
  for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
    if (file->subpackage == subpackage)
      switch (tolower(file->type))
      {
	case 'c' :
            fprintf(fp, "%%attr(%04o,%s,%s) %%config(noreplace) \"%s\"\n",
	            file->mode, file->user, file->group, file->dst);
            break;
	case 'd' :
            fprintf(fp, "%%attr(%04o,%s,%s) %%dir \"%s\"\n", file->mode,
	            file->user, file->group, file->dst);
            break;
	case 'f' :
	case 'l' :
            fprintf(fp, "%%attr(%04o,%s,%s) \"%s\"\n", file->mode, file->user,
	            file->group, file->dst);
            break;
	case 'i' :
	    if (format == PACKAGE_LSB)
	      fprintf(fp, "%%attr(0555,root,root) \"/etc/init.d/%s\"\n",
		      file->dst);
            else
	      fprintf(fp, "%%attr(0555,root,root) \"%s/init.d/%s\"\n",
	              SoftwareDir, file->dst);
            break;
      }

  return (0);
}
Beispiel #15
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
bspbrush_t *MergeBrushes( bspbrush_t *brushlist ) {
	int nummerges, merged;
	bspbrush_t *b1, *b2, *tail, *newbrush, *newbrushlist;
	bspbrush_t *lastb2;

	if ( !brushlist ) {
		return NULL;
	}

	qprintf( "%5d brushes merged", nummerges = 0 );
	do
	{
		for ( tail = brushlist; tail; tail = tail->next )
		{
			if ( !tail->next ) {
				break;
			}
		} //end for
		merged = 0;
		newbrushlist = NULL;
		for ( b1 = brushlist; b1; b1 = brushlist )
		{
			lastb2 = b1;
			for ( b2 = b1->next; b2; b2 = b2->next )
			{
				//if the brushes don't have the same contents
				if ( b1->original->contents != b2->original->contents ||
					 b1->original->expansionbbox != b2->original->expansionbbox ) {
					newbrush = NULL;
				} else { newbrush = TryMergeBrushes( b1, b2 );}
				if ( newbrush ) {
					tail->next = newbrush;
					lastb2->next = b2->next;
					brushlist = brushlist->next;
					FreeBrush( b1 );
					FreeBrush( b2 );
					for ( tail = brushlist; tail; tail = tail->next )
					{
						if ( !tail->next ) {
							break;
						}
					} //end for
					merged++;
					qprintf( "\r%5d", nummerges++ );
					break;
				} //end if
				lastb2 = b2;
			} //end for
			  //if b1 can't be merged with any of the other brushes
			if ( !b2 ) {
				brushlist = brushlist->next;
				//keep b1
				b1->next = newbrushlist;
				newbrushlist = b1;
			} //end else
		} //end for
		brushlist = newbrushlist;
	} while ( merged );
	qprintf( "\n" );
	return newbrushlist;
} //end of the function MergeBrushes
Beispiel #16
0
/*
 * The main glob() routine: compiles the pattern (optionally processing
 * quotes), calls glob1() to do the real pattern matching, and finally
 * sorts the list (unless unsorted operation is requested).  Returns 0
 * if things went well, nonzero if errors occurred.  It is not an error
 * to find no matches.
 */
static int
glob0(const Char *pattern, glob_t *pglob, struct glob_lim *limitp)
{
	const Char *qpatnext;
	int c, err, oldpathc;
	Char *bufnext, patbuf[PATH_MAX];

	qpatnext = globtilde(pattern, patbuf, PATH_MAX, pglob);
	oldpathc = pglob->gl_pathc;
	bufnext = patbuf;

	/* We don't need to check for buffer overflow any more. */
	while ((c = *qpatnext++) != EOS) {
		switch (c) {
		case LBRACKET:
			c = *qpatnext;
			if (c == NOT)
				++qpatnext;
			if (*qpatnext == EOS ||
			    g_strchr(qpatnext+1, RBRACKET) == NULL) {
				*bufnext++ = LBRACKET;
				if (c == NOT)
					--qpatnext;
				break;
			}
			*bufnext++ = M_SET;
			if (c == NOT)
				*bufnext++ = M_NOT;
			c = *qpatnext++;
			do {
				if (c == LBRACKET && *qpatnext == ':') {
					do {
						err = g_charclass(&qpatnext,
						    &bufnext);
						if (err)
							break;
						c = *qpatnext++;
					} while (c == LBRACKET && *qpatnext == ':');
					if (err == -1 &&
					    !(pglob->gl_flags & GLOB_NOCHECK))
						return GLOB_NOMATCH;
					if (c == RBRACKET)
						break;
				}
				*bufnext++ = CHAR(c);
				if (*qpatnext == RANGE &&
				    (c = qpatnext[1]) != RBRACKET) {
					*bufnext++ = M_RNG;
					*bufnext++ = CHAR(c);
					qpatnext += 2;
				}
			} while ((c = *qpatnext++) != RBRACKET);
			pglob->gl_flags |= GLOB_MAGCHAR;
			*bufnext++ = M_END;
			break;
		case QUESTION:
			pglob->gl_flags |= GLOB_MAGCHAR;
			*bufnext++ = M_ONE;
			break;
		case STAR:
			pglob->gl_flags |= GLOB_MAGCHAR;
			/* collapse adjacent stars to one,
			 * to avoid exponential behavior
			 */
			if (bufnext == patbuf || bufnext[-1] != M_ALL)
				*bufnext++ = M_ALL;
			break;
		default:
			*bufnext++ = CHAR(c);
			break;
		}
	}
	*bufnext = EOS;
#ifdef DEBUG
	qprintf("glob0:", patbuf);
#endif

	if ((err = glob1(patbuf, patbuf+PATH_MAX-1, pglob, limitp)) != 0)
		return(err);

	/*
	 * If there was no match we are going to append the pattern
	 * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
	 * and the pattern did not contain any magic characters
	 * GLOB_NOMAGIC is there just for compatibility with csh.
	 */
	if (pglob->gl_pathc == oldpathc) {
		if ((pglob->gl_flags & GLOB_NOCHECK) ||
		    ((pglob->gl_flags & GLOB_NOMAGIC) &&
		    !(pglob->gl_flags & GLOB_MAGCHAR)))
			return(globextend(pattern, pglob, limitp, NULL));
		else
			return(GLOB_NOMATCH);
	}
	if (!(pglob->gl_flags & GLOB_NOSORT)) {
		if ((pglob->gl_flags & GLOB_KEEPSTAT)) {
			/* Keep the paths and stat info synced during sort */
			struct glob_path_stat *path_stat;
			int i;
			int n = pglob->gl_pathc - oldpathc;
			int o = pglob->gl_offs + oldpathc;

			if ((path_stat = calloc(n, sizeof(*path_stat))) == NULL)
				return GLOB_NOSPACE;
			for (i = 0; i < n; i++) {
				path_stat[i].gps_path = pglob->gl_pathv[o + i];
				path_stat[i].gps_stat = pglob->gl_statv[o + i];
			}
			qsort(path_stat, n, sizeof(*path_stat), compare_gps);
			for (i = 0; i < n; i++) {
				pglob->gl_pathv[o + i] = path_stat[i].gps_path;
				pglob->gl_statv[o + i] = path_stat[i].gps_stat;
			}
			free(path_stat);
		} else {
			qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
			    pglob->gl_pathc - oldpathc, sizeof(char *),
			    compare);
		}
	}
	return(0);
}
Beispiel #17
0
/*
 * Recursive brace globbing helper. Tries to expand a single brace.
 * If it succeeds then it invokes globexp1 with the new pattern.
 * If it fails then it tries to glob the rest of the pattern and returns.
 */
static int
globexp2(const Char *ptr, const Char *pattern, glob_t *pglob,
    struct glob_lim *limitp)
{
	int     i, rv;
	Char   *lm, *ls;
	const Char *pe, *pm, *pl;
	Char    patbuf[PATH_MAX];

	/* copy part up to the brace */
	for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
		continue;
	*lm = EOS;
	ls = lm;

	/* Find the balanced brace */
	for (i = 0, pe = ++ptr; *pe; pe++)
		if (*pe == LBRACKET) {
			/* Ignore everything between [] */
			for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
				continue;
			if (*pe == EOS) {
				/*
				 * We could not find a matching RBRACKET.
				 * Ignore and just look for RBRACE
				 */
				pe = pm;
			}
		} else if (*pe == LBRACE)
			i++;
		else if (*pe == RBRACE) {
			if (i == 0)
				break;
			i--;
		}

	/* Non matching braces; just glob the pattern */
	if (i != 0 || *pe == EOS)
		return glob0(patbuf, pglob, limitp);

	for (i = 0, pl = pm = ptr; pm <= pe; pm++) {
		switch (*pm) {
		case LBRACKET:
			/* Ignore everything between [] */
			for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
				continue;
			if (*pm == EOS) {
				/*
				 * We could not find a matching RBRACKET.
				 * Ignore and just look for RBRACE
				 */
				pm = pl;
			}
			break;

		case LBRACE:
			i++;
			break;

		case RBRACE:
			if (i) {
				i--;
				break;
			}
			/* FALLTHROUGH */
		case COMMA:
			if (i && *pm == COMMA)
				break;
			else {
				/* Append the current string */
				for (lm = ls; (pl < pm); *lm++ = *pl++)
					continue;

				/*
				 * Append the rest of the pattern after the
				 * closing brace
				 */
				for (pl = pe + 1; (*lm++ = *pl++) != EOS; )
					continue;

				/* Expand the current pattern */
#ifdef DEBUG
				qprintf("globexp2:", patbuf);
#endif
				rv = globexp1(patbuf, pglob, limitp);
				if (rv && rv != GLOB_NOMATCH)
					return rv;

				/* move after the comma, to the next string */
				pl = pm + 1;
			}
			break;

		default:
			break;
		}
	}
	return 0;
}
Beispiel #18
0
void AAS_CreateCurveBrushes(void)
{
	int i, j, n, planenum, numcurvebrushes = 0;
	q3_dsurface_t *surface;
	q3_drawVert_t *dv_p;
	vec3_t points[MAX_PATCH_VERTS];
	int width, height, c;
	patchCollide_t *pc;
	facet_t *facet;
	mapbrush_t *brush;
	side_t *side;
	entity_t *mapent;
	winding_t *winding;

	qprintf("nummapbrushsides = %d\n", nummapbrushsides);
	mapent = &entities[0];
	for (i = 0; i < q3_numDrawSurfaces; i++)
	{
		surface = &q3_drawSurfaces[i];
		if ( ! surface->patchWidth ) continue;
		// if the curve is not solid
		if (!(q3_dshaders[surface->shaderNum].contentFlags & (CONTENTS_SOLID|CONTENTS_PLAYERCLIP)))
		{
			//Log_Print("skipped non-solid curve\n");
			continue;
		} //end if
		// if this curve should not be used for AAS
		if ( q3_dshaders[surface->shaderNum].contentFlags & CONTENTS_NOBOTCLIP ) {
			continue;
		}
		//
		width = surface->patchWidth;
		height = surface->patchHeight;
		c = width * height;
		if (c > MAX_PATCH_VERTS)
		{
			Error("ParseMesh: MAX_PATCH_VERTS");
		} //end if

		dv_p = q3_drawVerts + surface->firstVert;
		for ( j = 0 ; j < c ; j++, dv_p++ )
		{
			points[j][0] = dv_p->xyz[0];
			points[j][1] = dv_p->xyz[1];
			points[j][2] = dv_p->xyz[2];
		} //end for
		// create the internal facet structure
		pc = CM_GeneratePatchCollide(width, height, points);
		//
		for (j = 0; j < pc->numFacets; j++)
		{
			facet = &pc->facets[j];
			//
			brush = &mapbrushes[nummapbrushes];
			brush->original_sides = &brushsides[nummapbrushsides];
			brush->entitynum = 0;
			brush->brushnum = nummapbrushes - mapent->firstbrush;
			//
			brush->numsides = facet->numBorders + 2;
			nummapbrushsides += brush->numsides;
			brush->contents = CONTENTS_SOLID;
			//
			//qprintf("\r%6d curve brushes", nummapbrushsides);//++numcurvebrushes);
			qprintf("\r%6d curve brushes", ++numcurvebrushes);
			//
			planenum = FindFloatPlane(pc->planes[facet->surfacePlane].plane, pc->planes[facet->surfacePlane].plane[3]);
			//
			side = &brush->original_sides[0];
			side->planenum = planenum;
			side->contents = CONTENTS_SOLID;
			side->flags |= SFL_TEXTURED|SFL_VISIBLE|SFL_CURVE;
			side->surf = 0;
			//
			side = &brush->original_sides[1];
			if (create_aas)
			{
				//the plane is expanded later so it's not a problem that
				//these first two opposite sides are coplanar
				side->planenum = planenum ^ 1;
			} //end if
			else
			{
				side->planenum = FindFloatPlane(mapplanes[planenum^1].normal, mapplanes[planenum^1].dist + 1);
				side->flags |= SFL_TEXTURED|SFL_VISIBLE;
			} //end else
			side->contents = CONTENTS_SOLID;
			side->flags |= SFL_CURVE;
			side->surf = 0;
			//
			winding = BaseWindingForPlane(mapplanes[side->planenum].normal, mapplanes[side->planenum].dist);
			for (n = 0; n < facet->numBorders; n++)
			{
				//never use the surface plane as a border
				if (facet->borderPlanes[n] == facet->surfacePlane) continue;
				//
				side = &brush->original_sides[2 + n];
				side->planenum = FindFloatPlane(pc->planes[facet->borderPlanes[n]].plane, pc->planes[facet->borderPlanes[n]].plane[3]);
				if (facet->borderInward[n]) side->planenum ^= 1;
				side->contents = CONTENTS_SOLID;
				side->flags |= SFL_TEXTURED|SFL_CURVE;
				side->surf = 0;
				//chop the winding in place
				if (winding) ChopWindingInPlace(&winding, mapplanes[side->planenum^1].normal, mapplanes[side->planenum^1].dist, 0.1); //CLIP_EPSILON);
			} //end for
			//VectorCopy(pc->bounds[0], brush->mins);
			//VectorCopy(pc->bounds[1], brush->maxs);
			if (!winding)
			{
				Log_Print("WARNING: AAS_CreateCurveBrushes: no winding\n");
				brush->numsides = 0;
				continue;
			} //end if
			brush->original_sides[0].winding = winding;
			WindingBounds(winding, brush->mins, brush->maxs);
			for (n = 0; n < 3; n++)
			{
				//IDBUG: all the indexes into the mins and maxs were zero (not using i)
				if (brush->mins[n] < -MAX_MAP_BOUNDS || brush->maxs[n] > MAX_MAP_BOUNDS)
				{
					Log_Print("entity %i, brush %i: bounds out of range\n", brush->entitynum, brush->brushnum);
					Log_Print("brush->mins[%d] = %f, brush->maxs[%d] = %f\n", n, brush->mins[n], n, brush->maxs[n]);
					brush->numsides = 0; //remove the brush
					break;
				} //end if
				if (brush->mins[n] > MAX_MAP_BOUNDS || brush->maxs[n] < -MAX_MAP_BOUNDS)
				{
					Log_Print("entity %i, brush %i: no visible sides on brush\n", brush->entitynum, brush->brushnum);
					Log_Print("brush->mins[%d] = %f, brush->maxs[%d] = %f\n", n, brush->mins[n], n, brush->maxs[n]);
					brush->numsides = 0; //remove the brush
					break;
				} //end if
			} //end for
			if (create_aas)
			{
				//NOTE: brush bevels now already added
				//AddBrushBevels(brush);
				AAS_CreateMapBrushes(brush, mapent, false);
			} //end if
			else
			{
				// create windings for sides and bounds for brush
				MakeBrushWindings(brush);
				AddBrushBevels(brush);
				nummapbrushes++;
				mapent->numbrushes++;
			} //end else
		} //end for
	} //end for
	//qprintf("\r%6d curve brushes", nummapbrushsides);//++numcurvebrushes);
	qprintf("\r%6d curve brushes\n", numcurvebrushes);
} //end of the function AAS_CreateCurveBrushes
Beispiel #19
0
node_t *BuildTree_r( node_t *node, bspbrush_t *brushes ) {
	node_t      *newnode;
	side_t      *bestside;
	int i, totalmem;
	bspbrush_t  *children[2];

	qprintf( "\r%6d", numrecurse );
	numrecurse++;

	if ( numthreads == 1 ) {
		totalmem = WindingMemory() + c_nodememory + c_brushmemory;
		if ( totalmem > c_peak_totalbspmemory ) {
			c_peak_totalbspmemory = totalmem;
		}
		c_nodes++;
	} //endif

	if ( drawflag ) {
		DrawBrushList( brushes, node );
	}

	// find the best plane to use as a splitter
	bestside = SelectSplitSide( brushes, node );
	if ( !bestside ) {
		// leaf node
		node->side = NULL;
		node->planenum = -1;
		LeafNode( node, brushes );
		if ( node->contents & CONTENTS_SOLID ) {
			c_solidleafnodes++;
		}
		if ( create_aas ) {
			//free up memory!!!
			FreeBrushList( node->brushlist );
			node->brushlist = NULL;
			//free the node volume brush
			if ( node->volume ) {
				FreeBrush( node->volume );
				node->volume = NULL;
			} //end if
		} //end if
		return node;
	} //end if

	// this is a splitplane node
	node->side = bestside;
	node->planenum = bestside->planenum & ~1;   // always use front facing

	//split the brush list in two for both children
	SplitBrushList( brushes, node, &children[0], &children[1] );
	//free the old brush list
	FreeBrushList( brushes );

	// allocate children before recursing
	for ( i = 0; i < 2; i++ )
	{
		newnode = AllocNode();
		newnode->parent = node;
		node->children[i] = newnode;
	} //end for

	//split the volume brush of the node for the children
	SplitBrush( node->volume, node->planenum, &node->children[0]->volume,
				&node->children[1]->volume );

	if ( create_aas ) {
		//free the volume brush
		if ( node->volume ) {
			FreeBrush( node->volume );
			node->volume = NULL;
		} //end if
	} //end if
	  // recursively process children
	for ( i = 0; i < 2; i++ )
	{
		node->children[i] = BuildTree_r( node->children[i], children[i] );
	} //end for

	return node;
} //end of the function BuildTree_r
Beispiel #20
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
int AAS_StoreArea( tmp_area_t *tmparea ) {
	int side, edgenum, i;
	plane_t *plane;
	tmp_face_t *tmpface;
	aas_area_t *aasarea;
	aas_edge_t *edge;
	aas_face_t *aasface;
	aas_faceindex_t aasfacenum;
	vec3_t facecenter;
	winding_t *w;

	//when the area is merged go to the merged area
	//FIXME: this isn't necessary anymore because the tree
	//			is refreshed after area merging
	while ( tmparea->mergedarea ) tmparea = tmparea->mergedarea;
	//
	if ( tmparea->invalid ) {
		Error( "AAS_StoreArea: tried to store invalid area" );
	}
	//if there is an aas area already stored for this tmp area
	if ( tmparea->aasareanum ) {
		return -tmparea->aasareanum;
	}
	//
	if ( ( *aasworld ).numareas >= max_aas.max_areas ) {
		Error( "AAS_MAX_AREAS = %d", max_aas.max_areas );
	} //end if
	  //area zero is a dummy
	if ( ( *aasworld ).numareas == 0 ) {
		( *aasworld ).numareas = 1;
	}
	//create an area from this leaf
	aasarea = &( *aasworld ).areas[( *aasworld ).numareas];
	aasarea->areanum = ( *aasworld ).numareas;
	aasarea->numfaces = 0;
	aasarea->firstface = ( *aasworld ).faceindexsize;
	ClearBounds( aasarea->mins, aasarea->maxs );
	VectorClear( aasarea->center );
	//
//	Log_Write("tmparea %d became aasarea %d\r\n", tmparea->areanum, aasarea->areanum);
	//store the aas area number at the tmp area
	tmparea->aasareanum = aasarea->areanum;
	//
	for ( tmpface = tmparea->tmpfaces; tmpface; tmpface = tmpface->next[side] )
	{
		side = tmpface->frontarea != tmparea;
		//if there's an aas face created for the tmp face already
		if ( tmpface->aasfacenum ) {
			//we're at the back of the face so use a negative index
			aasfacenum = -tmpface->aasfacenum;
#ifdef DEBUG
			if ( tmpface->aasfacenum < 0 || tmpface->aasfacenum > max_aas.max_faces ) {
				Error( "AAS_CreateTree_r: face number out of range" );
			} //end if
#endif //DEBUG
			aasface = &( *aasworld ).faces[tmpface->aasfacenum];
			aasface->backarea = aasarea->areanum;
		} //end if
		else
		{
			plane = &mapplanes[tmpface->planenum ^ side];
			if ( side ) {
				w = tmpface->winding;
				tmpface->winding = ReverseWinding( tmpface->winding );
			} //end if
			if ( !AAS_GetFace( tmpface->winding, plane, 0, &aasfacenum ) ) {
				continue;
			}
			if ( side ) {
				FreeWinding( tmpface->winding );
				tmpface->winding = w;
			} //end if
			aasface = &( *aasworld ).faces[aasfacenum];
			aasface->frontarea = aasarea->areanum;
			aasface->backarea = 0;
			aasface->faceflags = tmpface->faceflags;
			//set the face number at the tmp face
			tmpface->aasfacenum = aasfacenum;
		} //end else
		  //add face points to the area bounds and
		  //calculate the face 'center'
		VectorClear( facecenter );
		for ( edgenum = 0; edgenum < aasface->numedges; edgenum++ )
		{
			edge = &( *aasworld ).edges[abs( ( *aasworld ).edgeindex[aasface->firstedge + edgenum] )];
			for ( i = 0; i < 2; i++ )
			{
				AddPointToBounds( ( *aasworld ).vertexes[edge->v[i]], aasarea->mins, aasarea->maxs );
				VectorAdd( ( *aasworld ).vertexes[edge->v[i]], facecenter, facecenter );
			} //end for
		} //end for
		VectorScale( facecenter, 1.0 / ( aasface->numedges * 2.0 ), facecenter );
		//add the face 'center' to the area 'center'
		VectorAdd( aasarea->center, facecenter, aasarea->center );
		//
		if ( ( *aasworld ).faceindexsize >= max_aas.max_faceindexsize ) {
			Error( "AAS_MAX_FACEINDEXSIZE = %d", max_aas.max_faceindexsize );
		} //end if
		( *aasworld ).faceindex[( *aasworld ).faceindexsize++] = aasfacenum;
		aasarea->numfaces++;
	} //end for
	  //if the area has no faces at all (return 0, = solid leaf)
	if ( !aasarea->numfaces ) {
		return 0;
	}
	//
	VectorScale( aasarea->center, 1.0 / aasarea->numfaces, aasarea->center );
	//Log_Write("area %d center %f %f %f\r\n", (*aasworld).numareas,
	//				aasarea->center[0], aasarea->center[1], aasarea->center[2]);
	//store the area settings
	AAS_StoreAreaSettings( tmparea->settings );
	//
	//Log_Write("tmp area %d became aas area %d\r\n", tmpareanum, aasarea->areanum);
	qprintf( "\r%6d", aasarea->areanum );
	//
	if ( ( *aasworld ).areasettings[aasarea->areanum].contents & AREACONTENTS_CLUSTERPORTAL ) {
		static int num;
		Log_Write( "***** area %d is a cluster portal %d\n", aasarea->areanum, num++ );
	} //end if
	  //
	( *aasworld ).numareas++;
	return -( ( *aasworld ).numareas - 1 );
} //end of the function AAS_StoreArea
Beispiel #21
0
/*
===========
MakeHullFaces
===========
*/
void MakeHullFaces (brush_t *b, brushhull_t *h)
{
    bface_t	*f, *f2;
    winding_t	*w;
    plane_t		*p;
    int			i, j;
    vec_t		v;
    vec_t		area;

restart:
    h->mins[0] = h->mins[1] = h->mins[2] = 9999;
    h->maxs[0] = h->maxs[1] = h->maxs[2] = -9999;

    for (f = h->faces ; f ; f=f->next)
    {
//		w = BaseWindingForIPlane (f->plane);
        w = BaseWindingForPlane (f->plane->normal, f->plane->dist);
        for (f2 = h->faces ; f2 && w ; f2=f2->next)
        {
            if (f == f2)
                continue;
            p = &mapplanes[f2->planenum ^ 1];

            w = ChopWinding (w, p->normal, p->dist);
        }
        area = w ? WindingArea(w) : 0;
        if (area < 0.1)
        {
            qprintf ("Entity %i, Brush %i: plane with area %4.2f\n"
                     , b->entitynum, b->brushnum, area);
            // remove the face and regenerate the hull
            if (h->faces == f)
                h->faces = f->next;
            else
            {
                for (f2=h->faces ; f2->next != f ; f2=f2->next)
                    ;
                f2->next = f->next;
            }
            goto restart;
        }
        f->w = w;
        f->contents = CONTENTS_EMPTY;
        if (w)
        {
            for (i=0 ; i<w->numpoints ; i++)
            {
                for (j=0 ; j<3 ; j++)
                {
                    v = w->p[i][j];
//					w->p[i][j] = floor (v+0.5);	// round to int
                    if (v<h->mins[j])
                        h->mins[j] = v;
                    if (v>h->maxs[j])
                        h->maxs[j] = v;
                }
            }
        }
    }

    for (i=0 ; i<3 ; i++)
    {
        if (h->mins[i] < -BOGUS_RANGE/2
                || h->maxs[i] > BOGUS_RANGE/2)
        {
            vec3_t eorigin = { 0, 0, 0};
            char *pszClass = "Unknown Class";
            if ( b->entitynum )
            {
                entity_t	*e = entities + b->entitynum;
                pszClass = ValueForKey(e, "classname" );
                GetVectorForKey( e, "origin", eorigin );
            }

            printf( "Entity %i, Brush %i: A '%s' @(%.0f,%.0f,%.0f)\n",
                    b->entitynum, b->brushnum, pszClass, eorigin[0], eorigin[1], eorigin[2] );
            printf( "\toutside world(+/-%d): (%.0f, %.0f, %.0f)-(%.0f,%.0f,%.0f)\n",
                    BOGUS_RANGE/2, h->mins[0], h->mins[1], h->mins[2], h->maxs[0], h->maxs[1], h->maxs[2] );
            break;
        }
    }
}
Beispiel #22
0
/*
==================
CSGFaces

Builds a list of surfaces containing all of the faces
==================
*/
void CSGFaces( tree_t *tree )
{
	int			i;
	qboolean	overwrite;
	brush_t		*b1, *b2;
	face_t		*f;

	qprintf( "---- CSGFaces ----\n" );

	memset( tree->validfaces, 0, sizeof( tree->validfaces ) );

	numcsgfaces = numcsgbrushfaces = numcsgmergefaces = 0;

	// do the solid faces
	for( b1 = tree->brushes; b1; b1 = b1->next ) {
		// set outside to a copy of the brush's faces
		CopyFacesToOutside( b1 );

		overwrite = false;
		for( b2 = tree->brushes; b2; b2 = b2->next ) {
			// see if b2 needs to clip a chunk out of b1
			if( b1 == b2 ) 	{
				overwrite = true;	// later brushes now overwrite
				continue;
			}

			// check bounding box first
			for( i = 0; i < 3; i++ ) {
				if( b1->mins[i] > b2->maxs[i] || b1->maxs[i] < b2->mins[i] )
					break;
			}
			if( i < 3 )
				continue;

			// divide faces by the planes of the new brush
			inside = outside;
			outside = NULL;

			for( f = b2->faces; f; f = f->next )
				ClipInside( f->planenum, f->planeside, overwrite );

			// these faces are continued in another brush, so get rid of them
			if( b1->contents == CONTENTS_SOLID && b2->contents <= CONTENTS_WATER )
				FreeInside( b2->contents );
			else
				FreeInside( CONTENTS_SOLID );
		}

		// all of the faces left in outside are real surface faces
//		if( b1->contents != CONTENTS_SOLID )
	   		if (b1->contents != CONTENTS_SOLID || func_water)//qb;  pOx - mirror insides for func_water entities
			SaveOutside( tree, true );	// mirror faces for inside view
		else
			SaveOutside( tree, false );
	}

	BuildSurfaces( tree );

	qprintf( "%5i brushfaces\n", numcsgbrushfaces );
	qprintf( "%5i csgfaces\n", numcsgfaces );
	qprintf( "%5i mergedfaces\n", numcsgmergefaces );
}
Beispiel #23
0
void AAS_MergeAreas( void ) {
	int side, nummerges, merges, groundfirst;
	tmp_area_t *tmparea, *othertmparea;
	tmp_face_t *face;

	nummerges = 0;
	Log_Write( "AAS_MergeAreas\r\n" );
	qprintf( "%6d areas merged", 1 );
	//
	groundfirst = true;
	//for (i = 0; i < 4 || merges; i++)
	while ( 1 )
	{
		//if (i < 2) groundfirst = true;
		//else groundfirst = false;
		//
		merges = 0;
		//first merge grounded areas only
		for ( tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next )
		{
			//if the area is invalid
			if ( tmparea->invalid ) {
				continue;
			} //end if
			  //
			if ( groundfirst ) {
				if ( !AAS_GroundArea( tmparea ) ) {
					continue;
				}
			} //end if
			  //
			for ( face = tmparea->tmpfaces; face; face = face->next[side] )
			{
				side = ( face->frontarea != tmparea );
				//if the face has both a front and back area
				if ( face->frontarea && face->backarea ) {
					//
					if ( face->frontarea == tmparea ) {
						othertmparea = face->backarea;
					} else { othertmparea = face->frontarea;}
					//
					if ( groundfirst ) {
						if ( !AAS_GroundArea( othertmparea ) ) {
							continue;
						}
					} //end if
					if ( AAS_TryMergeFaceAreas( face ) ) {
						qprintf( "\r%6d", ++nummerges );
						merges++;
						break;
					} //end if
				} //end if
			} //end for
		} //end for
		if ( !merges ) {
			if ( groundfirst ) {
				groundfirst = false;
			} else { break;}
		} //end if
	} //end for
	qprintf( "\n" );
	Log_Write( "%6d areas merged\r\n", nummerges );
	//refresh the merged tree
	AAS_RefreshMergedTree_r( tmpaasworld.nodes );
} //end of the function AAS_MergeAreas
Beispiel #24
0
/*
 * The main glob() routine: compiles the pattern (optionally processing
 * quotes), calls glob1() to do the real pattern matching, and finally
 * sorts the list (unless unsorted operation is requested).  Returns 0
 * if things went well, nonzero if errors occurred.  It is not an error
 * to find no matches.
 */
static int
glob0(const Char *pattern, glob_t *pglob)
{
	const Char *qpatnext;
	int c, err, oldpathc;
	Char *bufnext, patbuf[MAXPATHLEN+1];

	qpatnext = globtilde(pattern, patbuf, pglob);
	oldpathc = pglob->gl_pathc;
	bufnext = patbuf;

	/* We don't need to check for buffer overflow any more. */
	while ((c = *qpatnext++) != EOS) {
		switch (c) {
		case LBRACKET:
			c = *qpatnext;
			if (c == NOT)
				++qpatnext;
			if (*qpatnext == EOS ||
			    g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
				*bufnext++ = LBRACKET;
				if (c == NOT)
					--qpatnext;
				break;
			}
			*bufnext++ = M_SET;
			if (c == NOT)
				*bufnext++ = M_NOT;
			c = *qpatnext++;
			do {
				*bufnext++ = CHAR(c);
				if (*qpatnext == RANGE &&
				    (c = qpatnext[1]) != RBRACKET) {
					*bufnext++ = M_RNG;
					*bufnext++ = CHAR(c);
					qpatnext += 2;
				}
			} while ((c = *qpatnext++) != RBRACKET);
			pglob->gl_flags |= GLOB_MAGCHAR;
			*bufnext++ = M_END;
			break;
		case QUESTION:
			pglob->gl_flags |= GLOB_MAGCHAR;
			*bufnext++ = M_ONE;
			break;
		case STAR:
			pglob->gl_flags |= GLOB_MAGCHAR;
			/* collapse adjacent stars to one, 
			 * to avoid exponential behavior
			 */
			if (bufnext == patbuf || bufnext[-1] != M_ALL)
			    *bufnext++ = M_ALL;
			break;
		default:
			*bufnext++ = CHAR(c);
			break;
		}
	}
	*bufnext = EOS;
#ifdef DEBUG
	qprintf("glob0:", patbuf);
#endif

	if ((err = glob1(patbuf, pglob)) != 0)
		return(err);

	if (pglob->gl_pathc == oldpathc) {	
		/*
		 * If there was no match we are going to append the pattern 
		 * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was
		 * specified and the pattern did not contain any magic
		 * characters GLOB_NOMAGIC is there just for compatibility
		 * with csh.
		 */
		if ((pglob->gl_flags & GLOB_NOCHECK) ||
		    ((pglob->gl_flags & (GLOB_NOMAGIC|GLOB_MAGCHAR))
		     == GLOB_NOMAGIC)) {
			if ((err = globextend(pattern, pglob)) != 0)
				return (err);
		} else {
			return (GLOB_NOMATCH);
		}
	} else if (!(pglob->gl_flags & GLOB_NOSORT)) {
		qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
		    pglob->gl_pathc - oldpathc, sizeof(char *), compare);
	}

	return(0);
}
Beispiel #25
0
//===========================================================================
// Carves any intersecting solid brushes into the minimum number
// of non-intersecting brushes.
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
bspbrush_t *ChopBrushes (bspbrush_t *head)
{
	bspbrush_t	*b1, *b2, *next;
	bspbrush_t	*tail;
	bspbrush_t	*keep;
	bspbrush_t	*sub, *sub2;
	int			c1, c2;
	int num_csg_iterations;

	Log_Print("-------- Brush CSG ---------\n");
	Log_Print("%6d original brushes\n", CountBrushList (head));

	num_csg_iterations = 0;
	qprintf("%6d output brushes", num_csg_iterations);

#if 0
	if (startbrush == 0)
		WriteBrushList ("before.gl", head, false);
#endif
	keep = NULL;

newlist:
	// find tail
	if (!head) return NULL;

	for (tail = head; tail->next; tail = tail->next)
		;

	for (b1=head ; b1 ; b1=next)
	{
		next = b1->next;

		//if the conversion is cancelled
		if (cancelconversion)
		{
			b1->next = keep;
			keep = b1;
			continue;
		} //end if
		
		for (b2 = b1->next; b2; b2 = b2->next)
		{
			if (BrushesDisjoint (b1, b2))
				continue;

			sub = NULL;
			sub2 = NULL;
			c1 = 999999;
			c2 = 999999;

			if (BrushGE (b2, b1))
			{
				sub = SubtractBrush (b1, b2);
				if (sub == b1)
				{
					continue;		// didn't really intersect
				} //end if
				if (!sub)
				{	// b1 is swallowed by b2
					head = CullList (b1, b1);
					goto newlist;
				}
				c1 = CountBrushList (sub);
			}

			if ( BrushGE (b1, b2) )
			{
				sub2 = SubtractBrush (b2, b1);
				if (sub2 == b2)
					continue;		// didn't really intersect
				if (!sub2)
				{	// b2 is swallowed by b1
					FreeBrushList (sub);
					head = CullList (b1, b2);
					goto newlist;
				}
				c2 = CountBrushList (sub2);
			}

			if (!sub && !sub2)
				continue;		// neither one can bite

			// only accept if it didn't fragment
			// (commenting this out allows full fragmentation)
			if (c1 > 1 && c2 > 1)
			{
				if (sub2)
					FreeBrushList (sub2);
				if (sub)
					FreeBrushList (sub);
				continue;
			}

			if (c1 < c2)
			{
				if (sub2) FreeBrushList (sub2);
				tail = AddBrushListToTail (sub, tail);
				head = CullList (b1, b1);
				goto newlist;
			} //end if
			else
			{
				if (sub) FreeBrushList (sub);
				tail = AddBrushListToTail (sub2, tail);
				head = CullList (b1, b2);
				goto newlist;
			} //end else
		} //end for

		if (!b2)
		{	// b1 is no longer intersecting anything, so keep it
			b1->next = keep;
			keep = b1;
		} //end if
		num_csg_iterations++;
		qprintf("\r%6d", num_csg_iterations);
	} //end for

	if (cancelconversion) return keep;
	//
	qprintf("\n");
	Log_Write("%6d output brushes\r\n", num_csg_iterations);

#if 0
	{
		WriteBrushList ("after.gl", keep, false);
		WriteBrushMap ("after.map", keep);
	}
#endif

	return keep;
} //end of the function ChopBrushes
Beispiel #26
0
//===========================================================================
// create a tmp AAS area from a leaf node
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
tmp_node_t *AAS_CreateArea(node_t *node)
{
	int pside;
	int areafaceflags;
	portal_t	*p;
	tmp_face_t *tmpface;
	tmp_area_t *tmparea;
	tmp_node_t *tmpnode;

	//create an area from this leaf
	tmparea = AAS_AllocTmpArea();
	tmparea->tmpfaces = NULL;
	//clear the area face flags
	areafaceflags = 0;
	//make aas faces from the portals
	for (p = node->portals; p; p = p->next[pside])
	{
		pside = (p->nodes[1] == node);
		//don't create faces from very small portals
//		if (WindingArea(p->winding) < 1) continue;
		//if there's already a face created for this portal
		if (p->tmpface)
		{
			//add the back side of the face to the area
			AAS_AddFaceSideToArea(p->tmpface, 1, tmparea);
		} //end if
		else
		{
			tmpface = AAS_AllocTmpFace();
			//set the face pointer at the portal so we can see from
			//the portal there's a face created for it
			p->tmpface = tmpface;
			//FIXME: test this change
			//tmpface->planenum = (p->planenum & ~1) | pside;
			tmpface->planenum = p->planenum ^ pside;
			if (pside) tmpface->winding = ReverseWinding(p->winding);
			else tmpface->winding = CopyWinding(p->winding);
#ifdef L_DEBUG
			//
			AAS_CheckFaceWindingPlane(tmpface);
#endif //L_DEBUG
			//if there's solid at the other side of the portal
			if (p->nodes[!pside]->contents & (CONTENTS_SOLID | CONTENTS_PLAYERCLIP))
			{
				tmpface->faceflags |= FACE_SOLID;
			} //end if
			//else there is no solid at the other side and if there
			//is a liquid at this side
			else if (node->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA))
			{
				tmpface->faceflags |= FACE_LIQUID;
				//if there's no liquid at the other side
				if (!(p->nodes[!pside]->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA)))
				{
					tmpface->faceflags |= FACE_LIQUIDSURFACE;
				} //end if
			} //end else
			//if there's ladder contents at other side of the portal
			if ((p->nodes[pside]->contents & CONTENTS_LADDER) ||
					(p->nodes[!pside]->contents & CONTENTS_LADDER))
			{

				//NOTE: doesn't have to be solid at the other side because
				// when standing one can use a crouch area (which is not solid)
				// as a ladder
				// imagine a ladder one can walk underthrough,
				// under the ladder against the ladder is a crouch area
				// the (vertical) sides of this crouch area area also used as
				// ladder sides when standing (not crouched)
				tmpface->faceflags |= FACE_LADDER;
			} //end if
			//if it is possible to stand on the face
			if (AAS_GroundFace(tmpface))
			{
				tmpface->faceflags |= FACE_GROUND;
			} //end if
			//
			areafaceflags |= tmpface->faceflags;
			//no aas face number yet (zero is a dummy in the aasworld faces)
			tmpface->aasfacenum = 0;
			//add the front side of the face to the area
			AAS_AddFaceSideToArea(tmpface, 0, tmparea);
		} //end else
	} //end for
	qprintf("\r%6d", tmparea->areanum);
	//presence type in the area
	tmparea->presencetype = ~node->expansionbboxes & cfg.allpresencetypes;
	//
	tmparea->contents = 0;
	if (node->contents & CONTENTS_CLUSTERPORTAL) tmparea->contents |= AREACONTENTS_CLUSTERPORTAL;
	if (node->contents & CONTENTS_MOVER) tmparea->contents |= AREACONTENTS_MOVER;
	if (node->contents & CONTENTS_TELEPORTER) tmparea->contents |= AREACONTENTS_TELEPORTER;
	if (node->contents & CONTENTS_JUMPPAD) tmparea->contents |= AREACONTENTS_JUMPPAD;
	if (node->contents & CONTENTS_DONOTENTER) tmparea->contents |= AREACONTENTS_DONOTENTER;
	if (node->contents & CONTENTS_WATER) tmparea->contents |= AREACONTENTS_WATER;
	if (node->contents & CONTENTS_LAVA) tmparea->contents |= AREACONTENTS_LAVA;
	if (node->contents & CONTENTS_SLIME) tmparea->contents |= AREACONTENTS_SLIME;
	if (node->contents & CONTENTS_NOTTEAM1) tmparea->contents |= AREACONTENTS_NOTTEAM1;
	if (node->contents & CONTENTS_NOTTEAM2) tmparea->contents |= AREACONTENTS_NOTTEAM2;

	//store the bsp model that's inside this node
	tmparea->modelnum = node->modelnum;
	//sorta check for flipped area faces (remove??)
	AAS_FlipAreaFaces(tmparea);
	//check if the area is ok (remove??)
	AAS_CheckArea(tmparea);
	//
	tmpnode = AAS_AllocTmpNode();
	tmpnode->planenum = 0;
	tmpnode->children[0] = 0;
	tmpnode->children[1] = 0;
	tmpnode->tmparea = tmparea;
	//
	return tmpnode;
} //end of the function AAS_CreateArea
Beispiel #27
0
void 
SiteHandlerStream::HandleStream(EventStream* p_stream)
{
  bool result = false;

  // Use the event stream
  testStream = p_stream;
  HTTPServer* server = p_stream->m_site->GetHTTPServer();

  // Report it
  xprintf("NEW EVENT STREAM : %p\n", (void*)testStream);

  for(int x = 1; x <= EventTests; ++x)
  {
    ServerEvent* eventx = new ServerEvent("message");
    eventx->m_id = x;
    eventx->m_data.Format("This is message number: %u\n",x);

    result = server->SendEvent(p_stream,eventx);

    // --- "---------------------------------------------- - ------
    qprintf("Event stream OnMessage %d sent                  : %s\n", x, result ? "OK" : "ERROR");
    if(result) 
    {
      --totalChecks;
    }
    else
    {
      xerror();
    }
    // Waiting long time to see if the flush works and testing event streams
    // with immediately reaction on the client
    // Sleep(20000);

    // Wait 1/10 of a second
    Sleep(100);
  }

  xprintf("Sending other messages\n");
  ServerEvent* ander = new ServerEvent("other");
  ander->m_id   = 1;
  ander->m_data = "This is a complete different message in another set of stories.";
  result = server->SendEvent(p_stream,ander);
  // --- "---------------------------------------------- - ------
  qprintf("Event stream 'other' message sent              : %s\n", result ? "OK" : "ERROR");
  if(result) 
  {
    --totalChecks;
  }
  else
  {
    xerror();
  }

  xprintf("Sending an error message\n");
  ServerEvent* err = new ServerEvent("error");
  err->m_id = 0;
  err->m_data = "This is a very serious bug report from your server! Heed attention to it!";
  result = server->SendEvent(p_stream,err);
  // --- "---------------------------------------------- - ------
  qprintf("Event stream 'OnError' message sent            : %s\n", result ? "OK" : "ERROR");
  if(result)
  {
    --totalChecks;
  }
  else
  {
    xerror();
  }

  // Implicitly sending an OnClose
  xprintf("Closing event stream\n");
  server->CloseEventStream(p_stream);

  // Check for closed stream
  result = !server->HasEventStream(p_stream);
  // --- "---------------------------------------------- - ------
  qprintf("Event stream closed by server (OnClose sent)   : %s\n", result ? "OK" : "ERROR");
  if(result)
  {
    --totalChecks;
  }
  else
  {
    xerror(); 
  }
}
Beispiel #28
0
//===========================================================================
// find an area with ladder faces and ground faces that are not connected
// split the area with a horizontal plane at the lowest vertex of all
// ladder faces in the area
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
tmp_node_t *AAS_LadderSubdivideArea_r( tmp_node_t *tmpnode ) {
	int side1, i, planenum;
	int foundladderface, foundgroundface;
	float dist;
	tmp_area_t *tmparea, *frontarea, *backarea;
	tmp_face_t *face1;
	tmp_node_t *tmpnode1, *tmpnode2;
	vec3_t lowestpoint, normal = {0, 0, 1};
	plane_t *plane;
	winding_t *w;

	tmparea = tmpnode->tmparea;
	//skip areas with a liquid
	if ( tmparea->contents & ( AREACONTENTS_WATER
							   | AREACONTENTS_LAVA
							   | AREACONTENTS_SLIME ) ) {
		return tmpnode;
	}
	//must be possible to stand in the area
	if ( !( tmparea->presencetype & PRESENCE_STAND ) ) {
		return tmpnode;
	}
	//
	foundladderface = false;
	foundgroundface = false;
	lowestpoint[2] = 99999;
	//
	for ( face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1] )
	{
		//side of the face the area is on
		side1 = face1->frontarea != tmparea;
		//if the face is a ladder face
		if ( face1->faceflags & FACE_LADDER ) {
			plane = &mapplanes[face1->planenum];
			//the ladder face plane should be pretty much vertical
			if ( DotProduct( plane->normal, normal ) > -0.1 ) {
				foundladderface = true;
				//find lowest point
				for ( i = 0; i < face1->winding->numpoints; i++ )
				{
					if ( face1->winding->p[i][2] < lowestpoint[2] ) {
						VectorCopy( face1->winding->p[i], lowestpoint );
					} //end if
				} //end for
			} //end if
		} //end if
		else if ( face1->faceflags & FACE_GROUND ) {
			foundgroundface = true;
		} //end else if
	} //end for
	  //
	if ( ( !foundladderface ) || ( !foundgroundface ) ) {
		return tmpnode;
	}
	//
	for ( face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1] )
	{
		//side of the face the area is on
		side1 = face1->frontarea != tmparea;
		//if the face isn't a ground face
		if ( !( face1->faceflags & FACE_GROUND ) ) {
			continue;
		}
		//the ground plane
		plane = &mapplanes[face1->planenum];
		//get the difference between the ground plane and the lowest point
		dist = DotProduct( plane->normal, lowestpoint ) - plane->dist;
		//if the lowest point is very near one of the ground planes
		if ( dist > -1 && dist < 1 ) {
			return tmpnode;
		} //end if
	} //end for
	  //
	dist = DotProduct( normal, lowestpoint );
	planenum = FindFloatPlane( normal, dist, 1, (vec3_t*)&lowestpoint );
	//
	w = AAS_SplitWinding( tmparea, planenum );
	if ( !w ) {
		return tmpnode;
	}
	FreeWinding( w );
	//split the area with a horizontal plane through the lowest point
	qprintf( "\r%6d", ++numladdersubdivisions );
	//
	AAS_SplitArea( tmparea, planenum, &frontarea, &backarea );
	//
	tmpnode->tmparea = NULL;
	tmpnode->planenum = planenum;
	//
	tmpnode1 = AAS_AllocTmpNode();
	tmpnode1->planenum = 0;
	tmpnode1->tmparea = frontarea;
	//
	tmpnode2 = AAS_AllocTmpNode();
	tmpnode2->planenum = 0;
	tmpnode2->tmparea = backarea;
	//subdivide the areas created by splitting recursively
	tmpnode->children[0] = AAS_LadderSubdivideArea_r( tmpnode1 );
	tmpnode->children[1] = AAS_LadderSubdivideArea_r( tmpnode2 );
	//refresh the tree
	AAS_RefreshLadderSubdividedTree_r( tmpaasworld.nodes, tmparea, tmpnode1, tmpnode2, planenum );
	//
	return tmpnode;
} //end of the function AAS_LadderSubdivideArea_r
Beispiel #29
0
/*
================
SplitBrush

Generates two new brushes, leaving the original
unchanged
================
*/
void SplitBrush (bspbrush_t *brush, int planenum,
	bspbrush_t **front, bspbrush_t **back)
{
	bspbrush_t	*b[2];
	int			i, j;
	winding_t	*w, *cw[2], *midwinding;
	plane_t		*plane, *plane2;
	side_t		*s, *cs;
	float		d, d_front, d_back;

	*front = *back = NULL;
	plane = &mapplanes[planenum];

	// check all points
	d_front = d_back = 0;
	for (i=0 ; i<brush->numsides ; i++)
	{
		w = brush->sides[i].winding;
		if (!w)
			continue;
		for (j=0 ; j<w->numpoints ; j++)
		{
			d = DotProduct (w->p[j], plane->normal) - plane->dist;
			if (d > 0 && d > d_front)
				d_front = d;
			if (d < 0 && d < d_back)
				d_back = d;
		}
	}
	if (d_front < 0.1) // PLANESIDE_EPSILON)
	{	// only on back
		*back = CopyBrush (brush);
		return;
	}
	if (d_back > -0.1) // PLANESIDE_EPSILON)
	{	// only on front
		*front = CopyBrush (brush);
		return;
	}

	// create a new winding from the split plane

	w = BaseWindingForPlane (plane->normal, plane->dist);
	for (i=0 ; i<brush->numsides && w ; i++)
	{
		plane2 = &mapplanes[brush->sides[i].planenum ^ 1];
		ChopWindingInPlace (&w, plane2->normal, plane2->dist, 0); // PLANESIDE_EPSILON);
	}

	if (!w || WindingIsTiny (w) )
	{	// the brush isn't really split
		int		side;

		side = BrushMostlyOnSide (brush, plane);
		if (side == PSIDE_FRONT)
			*front = CopyBrush (brush);
		if (side == PSIDE_BACK)
			*back = CopyBrush (brush);
		return;
	}

	if (WindingIsHuge (w))
	{
		qprintf ("WARNING: huge winding\n");
	}

	midwinding = w;

	// split it for real

	for (i=0 ; i<2 ; i++)
	{
		b[i] = AllocBrush (brush->numsides+1);
		b[i]->original = brush->original;
	}

	// split all the current windings

	for (i=0 ; i<brush->numsides ; i++)
	{
		s = &brush->sides[i];
		w = s->winding;
		if (!w)
			continue;
		ClipWindingEpsilon (w, plane->normal, plane->dist,
			0 /*PLANESIDE_EPSILON*/, &cw[0], &cw[1]);
		for (j=0 ; j<2 ; j++)
		{
			if (!cw[j])
				continue;
#if 0
			if (WindingIsTiny (cw[j]))
			{
				FreeWinding (cw[j]);
				continue;
			}
#endif
			cs = &b[j]->sides[b[j]->numsides];
			b[j]->numsides++;
			*cs = *s;
//			cs->planenum = s->planenum;
//			cs->texinfo = s->texinfo;
//			cs->visible = s->visible;
//			cs->original = s->original;
			cs->winding = cw[j];
			cs->tested = false;
		}
	}


	// see if we have valid polygons on both sides

	for (i=0 ; i<2 ; i++)
	{
		BoundBrush (b[i]);
		for (j=0 ; j<3 ; j++)
		{
			if (b[i]->mins[j] < -4096 || b[i]->maxs[j] > 4096)
			{
				qprintf ("bogus brush after clip\n");
				break;
			}
		}

		if (b[i]->numsides < 3 || j < 3)
		{
			FreeBrush (b[i]);
			b[i] = NULL;
		}
	}

	if ( !(b[0] && b[1]) )
	{
		if (!b[0] && !b[1])
			qprintf ("split removed brush\n");
		else
			qprintf ("split not on both sides\n");
		if (b[0])
		{
			FreeBrush (b[0]);
			*front = CopyBrush (brush);
		}
		if (b[1])
		{
			FreeBrush (b[1]);
			*back = CopyBrush (brush);
		}
		return;
	}

	// add the midwinding to both sides
	for (i=0 ; i<2 ; i++)
	{
		cs = &b[i]->sides[b[i]->numsides];
		b[i]->numsides++;

		cs->planenum = planenum^i^1;
		cs->texinfo = TEXINFO_NODE;
		cs->visible = false;
		cs->tested = false;
		if (i==0)
			cs->winding = CopyWinding (midwinding);
		else
			cs->winding = midwinding;
	}

{
	vec_t	v1;
	int		i;

	for (i=0 ; i<2 ; i++)
	{
		v1 = BrushVolume (b[i]);
		if (v1 < 1.0)
		{
			FreeBrush (b[i]);
			b[i] = NULL;
//			qprintf ("tiny volume after clip\n");
		}
	}
}

	*front = b[0];
	*back = b[1];
}
Beispiel #30
0
//===========================================================================
//
// Parameter:               -
// Returns:                 -
// Changes Globals:     -
//===========================================================================
void AAS_CreateAreaSettings(void)
{
	int i, flags, side, numgrounded, numladderareas, numliquidareas;
	tmp_face_t *face;
	tmp_area_t *tmparea;
	int count;

	numgrounded = 0;
	numladderareas = 0;
	numliquidareas = 0;
	Log_Write("AAS_CreateAreaSettings\r\n");
	i = 0;
	qprintf("%6d areas provided with settings", i);

	for(tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
	{
		//if the area is invalid there no need to create settings for it
		if(tmparea->invalid)
		{
			continue;
		}

		tmparea->settings = (tmp_areasettings_t *) GetClearedMemory(sizeof(tmp_areasettings_t));
		tmparea->settings->contents = tmparea->contents;
		tmparea->settings->modelnum = tmparea->modelnum;
		flags = 0;
		count = 0;
		tmparea->settings->groundsteepness = 0.0;

		for(face = tmparea->tmpfaces; face; face = face->next[side])
		{
			side = face->frontarea != tmparea;
			flags |= face->faceflags;

			// Ridah, add this face's steepness
			if(face->faceflags & FACE_GROUND)
			{
				tmparea->settings->groundsteepness += (1.0 - mapplanes[face->planenum ^ side].normal[2]);
				count++;
			}
		} //end for

		tmparea->settings->groundsteepness /= (float)count;

		if(tmparea->settings->groundsteepness > 1.0)
		{
			tmparea->settings->groundsteepness = 1.0;
		}

		if(tmparea->settings->groundsteepness < 0.0)
		{
			tmparea->settings->groundsteepness = 0.0;
		}

		tmparea->settings->areaflags = 0;

		if(flags & FACE_GROUND)
		{
			tmparea->settings->areaflags |= AREA_GROUNDED;
			numgrounded++;
		} //end if

		if(flags & FACE_LADDER)
		{
			tmparea->settings->areaflags |= AREA_LADDER;
			numladderareas++;
		} //end if

		if(tmparea->contents & (AREACONTENTS_WATER |
		                        AREACONTENTS_SLIME |
		                        AREACONTENTS_LAVA))
		{
			tmparea->settings->areaflags |= AREA_LIQUID;
			numliquidareas++;
		} //end if

		//presence type of the area
		tmparea->settings->presencetype = tmparea->presencetype;
		//
		qprintf("\r%6d", ++i);
	} //end for

	qprintf("\n");
#ifdef AASINFO
	Log_Print("%6d grounded areas\n", numgrounded);
	Log_Print("%6d ladder areas\n", numladderareas);
	Log_Print("%6d liquid areas\n", numliquidareas);
#endif //AASINFO
} //end of the function AAS_CreateAreaSettings