static void EmitAreaLeaves(area_t *a, FILE *fp) { // emit the leaf numbers EmitInt(a->numleafs, fp); for (bspnode_t *n = a->leafs; n; n = n->areanext) EmitInt(n->nodenumber, fp); }
static void EmitNodeBlock(bsptree_t *tree, FILE *fp) { NumberNodesRecursive(tree->root, 0); EmitHeader("nodes", fp); EmitInt(tree->numnodes, fp); EmitInt(tree->numleafs, fp); for (int i = 0; i < tree->numnodes; i++) EmitNode(i, tree->root, fp); }
// emit nodes in pre-order static int EmitNode(bspnode_t *n, FILE *fp) { // termination guard if (!n) return; children[0] = EmitNode(n->children[0]); children[1] = EmitNode(n->children[1]); EmitInt(children[0]); EmitInt(children[1]); // write the node data EmitNodeData(); }
static void EmitNodeBlock(bsptree_t *tree, FILE *fp) { NumberNodesRecursive(tree->root, 0); EmitInt(tree->numnodes, fp); EmitInt(tree->numleafs, fp); for (int i = 0; i < tree->numnodes; i++) { for (bspnode_t *n = tree->nodes; n; n = n->treenext) if (n->nodenumber == i) break; EmitNode(n, fp); } }
// emit nodes in post-order in place static void EmitNode(bspnode_t *n, FILE *fp) { // termination guard if (!n) return; // write the node data EmitNodeData(); // write a flag that indicates whether the node has children EmitInt((n->children[0] != NULL ? 1 : 0), fp); EmitInt((n->children[1] != NULL ? 1 : 0), fp); // emit the child nodes EmitNode(n->children[0], fp); EmitNode(n->children[1], fp); }
// emit nodes in post-order. This order must match how the nodes were numbered // an alternative would be to write these out iteratively and fseek to the correct position static void EmitNode(bspnode_t *n, FILE *fp) { // termination guard if (!n) return; // emit the child node numbers EmitInt((n->children[0] ? n->children[0]->nodenumber : -1), fp); EmitInt((n->children[1] ? n->children[1]->nodenumber : -1), fp); #if 1 // write the node data (disable this to check the node linkage) EmitPlane(n->plane, fp); EmitBox3(n->box, fp); EmitInt((n->area ? n->area->areanumber : -1), fp); EmitInt(n->empty ? 1 : 0, fp); #endif }
static void EmitAreaBlock(bsptree_t *tree, FILE *fp) { NumberAreasRecursive(tree->areas, 0); EmitHeader("areas", fp); EmitInt(tree->numareas, fp); for (area_t *a = tree->areas; a; a = a->next) EmitArea(a, fp); }
static void EmitPortalBlock(bsptree_t *tree, FILE *fp) { EmitHeader("portals", fp); EmitInt(tree->numportals, fp); for (portal_t *p = tree->portals; p; p = p->treenext) { EmitInt(p->srcleaf->nodenumber, fp); EmitInt(p->dstleaf->nodenumber, fp); polygon_t *polygon = p->polygon; EmitInt(polygon->numvertices, fp); for (int i = 0; i < polygon->numvertices; i++) { EmitFloat(polygon->vertices[i][0], fp); EmitFloat(polygon->vertices[i][1], fp); EmitFloat(polygon->vertices[i][2], fp); } } }
static void EmitAreaRenderModel(area_t *a, FILE *fp) { EmitHeader("rmodel", fp); EmitString(fp, "area%04i", a->areanumber); BeginMesh(); for (areatri_t *t = a->trilist->head; t; t = t->next) { // fixme: function to create these meshvertex_t v0, v1, v2; v0.xyz = t->vertices[0]; v0.normal = t->normals[0]; v1.xyz = t->vertices[1]; v1.normal = t->normals[1]; v2.xyz = t->vertices[2]; v2.normal = t->normals[2]; InsertTri(v0, v1, v2); } EndMesh(); // emit the vertex block int numvertices = NumVertices(); EmitInt(numvertices, fp); for (int i = 0; i < numvertices; i++) { meshvertex_t v = GetVertex(i); EmitFloat(v.xyz[0], fp); EmitFloat(v.xyz[1], fp); EmitFloat(v.xyz[2], fp); EmitFloat(v.normal[0], fp); EmitFloat(v.normal[1], fp); EmitFloat(v.normal[2], fp); } // emit the index block int numindicies = NumIndicies(); EmitInt(numindicies, fp); for (int i = 0; i < numindicies; i++) EmitInt(GetIndex(i), fp); }
static void EmitString(FILE *fp, const char *format, ...) { va_list valist; char buffer[2048]; va_start(valist, format); vsprintf(buffer, format, valist); va_end(valist); EmitInt(strlen(buffer), fp); fprintf(fp, "%s", buffer); }
// search for node with number 'num' and emit the node data into the file stream // fixme: split this into a search and emit operation rather than combining both? static void EmitNode(int num, bspnode_t *n, FILE *fp) { // termination guard if (!n) return; // keep searching for the node in the tree if (n->nodenumber != num) { EmitNode(num, n->children[0], fp); EmitNode(num, n->children[1], fp); return; } // emit the child node numbers EmitInt((n->children[0] ? n->children[0]->nodenumber : -1), fp); EmitInt((n->children[1] ? n->children[1]->nodenumber : -1), fp); // write the node data EmitPlane(n->plane, fp); EmitBox3(n->box, fp); }
static void EmitStaticRenderModel(smodel_t *m, FILE *fp) { static int count = 0; EmitHeader("rmodel", fp); EmitString(fp, "staticmodel%04i", count); // emit the vertex block EmitInt(m->numvertices, fp); for (int i = 0; i < m->numvertices; i++) { EmitFloat(m->vertices[i][0], fp); EmitFloat(m->vertices[i][1], fp); EmitFloat(m->vertices[i][2], fp); EmitFloat(0.0f, fp); EmitFloat(0.0f, fp); EmitFloat(1.0f, fp); } // emit the index block EmitInt(m->numindicies, fp); for (int i = 0; i < m->numindicies; i++) EmitInt(m->indicies[i], fp); }
void EmitVarName(Var * var) /* Purpose: Emit name of variable. Variable name may contain non-alphanumeric characters, so we must translate them to support ordinary assemblers. Identifiers starting with digit are prefixed by _N. Non-alphanumeric characters are replaced by xNN, when NN are two hexadecimal digits representing ascii code of the character. */ { char * s, c; s = var->name; if (s != NULL) { // If identifier starts with number, we prefix _N c = *s; if (c >='0' && c <= '9') { EmitChar('_'); EmitChar('N'); } while(c = *s++) { if (c == '\'') { EmitChar('_'); c = '_'; } if (c == '_' || (c >= 'a' && c <= 'z') || (c>='A' && c<='Z') || (c>='0' && c<='9')) { EmitChar(c); } else { EmitChar('x'); EmitHex(c); } } } // If variable has index, append the index if (var->idx != 0) EmitInt(var->idx-1); }
void EmitInstr2(Instr * instr, char * str) { Var * var; UInt8 format = 0; char * s, c; UInt32 n; BigInt bn; BigInt * pn; s = str; if (instr->op == INSTR_LINE) { PrintColor(BLUE+LIGHT); } while(c = *s++) { if (c == '%') { c = *s++; if (c == '\'') { format = 1; c = *s++; } if (c >='A' && c<='Z') { var = MACRO_ARG[c-'A']; // Variable properties if (*s == '.') { s++; if (StrEqualPrefix(s, "count", 5)) { VarCount(var, &bn); EmitBigInt(&bn); s+= 5; continue; } else if (StrEqualPrefix(s, "size", 4)) { n = VarByteSize(var); EmitInt(n); s+= 4; continue; } else if (StrEqualPrefix(s, "elemsize", 8) || StrEqualPrefix(s, "item.size", 9)) { s += 8; if (var->type->variant == TYPE_ARRAY) { n = TypeSize(var->type->element); } else { n = 0; } EmitInt(n); continue; } if (StrEqualPrefix(s, "step", 4)) { s += 4; n = 1; if (var->type->variant == TYPE_ARRAY) { n = var->type->step; } EmitInt(n); continue; } else if (StrEqualPrefix(s, "index.min", 9)) { s += 9; if (var->type->variant == TYPE_ARRAY) { pn = &var->type->index->range.min; } else { pn = Int0(); } EmitBigInt(pn); continue; } s--; } EmitVar(var, format); continue; } switch(c) { case '0': EmitVar(instr->result, format); continue; case '1': if (instr->op != INSTR_LINE) { EmitVar(instr->arg1, format); } else { EmitInt(instr->line_no); } continue; case '2': if (instr->op != INSTR_LINE) { EmitVar(instr->arg2, format); } else { EmitStr(instr->line); } continue; case '@': break; case 't': c = '\t'; break; } } EmitChar(c); } if (instr->op == INSTR_LINE) { PrintColor(RED+GREEN+BLUE); } }
void EmitBigInt(BigInt * n) { Int32 i; i = IntN(n); EmitInt(i); }