/* =========== 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; }
/* 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; }
/* ================= 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; }
/* ===================== 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 ); }
//=========================================================================== // // 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
/* * 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; }
//=========================================================================== // 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
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; }
/* * 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); }
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; }
/* =============== 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); } }
/* =========== 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); } }
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; }
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); }
//=========================================================================== // // 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
/* * 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); }
/* * 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; }
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
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
//=========================================================================== // // 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
/* =========== 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; } } }
/* ================== 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 ); }
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
/* * 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); }
//=========================================================================== // 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
//=========================================================================== // 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
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(); } }
//=========================================================================== // 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
/* ================ 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]; }
//=========================================================================== // // 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