#include #include "print.h" #define INDENT " " static void print_indent(FILE *f, unsigned int indent) { for (unsigned int i = 0; i < indent; i++) fprintf(f, INDENT); } void print_token(FILE *f, struct token *tok, unsigned int indent) { print_indent(f, indent); switch (tok->type) { case TOKEN_NUMBER: fprintf(f, "%f\n", tok->number); break; case TOKEN_STRING: fprintf(f, "\"%.*s\"\n", PSTR(tok->string)); break; case TOKEN_VAR: fprintf(f, "$%.*s\n", PSTR(tok->var)); break; case TOKEN_IDENT: fprintf(f, "%.*s\n", PSTR(tok->ident)); break; case TOKEN_OP: fprintf(f, "(#%d", tok->op.type); if (tok->op.children.len) fprintf(f, "\n"); for (size_t i = 0; i < tok->op.children.len; i++) print_token(f, &tok->op.children.ptr[i], indent+1); if (tok->op.children.len) print_indent(f, indent); fprintf(f, ")\n"); break; } } void print_expr(FILE *f, struct expr *expr) { switch (expr->type) { case EXPR_NUMBER: fprintf(f, "%f", expr->number); break; case EXPR_TIME: fprintf(f, "(time)"); break; case EXPR_OP: fprintf(f, "(%.*s", PSTR(op_name_tab[expr->op.type])); for (size_t i = 0; i < expr->op.args.len; i++) { fprintf(f, " "); print_expr(f, &expr->op.args.ptr[i]); } fprintf(f, ")"); break; } } void print_seq(FILE *f, size_t n_inst, struct seq_inst inst[n_inst], enum scene_stage stage) { for (size_t i = 0; i < n_inst; i++) { if (i) fprintf(f, " "); switch (inst[i].type) { case SEQ_TIME: fprintf(f, "%f", inst[i].time); break; case SEQ_POV: if (stage >= SCENE_BOUND) fprintf(f, "(pov %p)", inst[i].pov); else fprintf(f, "(pov %.*s)", PSTR(inst[i].pov_name.str)); break; case SEQ_REP: fprintf(f, "(rep "); if (inst[i].rep.times == SEQ_TIMES_INF) fprintf(f, "inf: "); else fprintf(f, "%u: ", inst[i].rep.times); print_seq(f, inst[i].rep.children.len, inst[i].rep.children.ptr, stage); fprintf(f, ")"); break; } } } void print_surface(FILE *f, struct surface *surf, enum scene_stage stage) { fprintf(f, "(color "); print_expr(f, &surf->color); fprintf(f, ")"); if (!surf->texture.present) return; if (stage >= SCENE_LOADED) { fprintf(f, " (texture #%"PRItexture_id")", surf->texture.data.id); } else { switch (surf->texture.data.source.type) { case TEXTURE_2D: fprintf(f, " (texture "); break; case TEXTURE_CUBEMAP: fprintf(f, " (cubemap "); break; } fprintf(f, "%.*s)", PSTR(surf->texture.data.source.path.str)); } } void print_node(FILE *f, struct node *node, enum scene_stage stage, unsigned int indent) { print_indent(f, indent); switch (node->type) { case NODE_TRANSFORM: { fprintf(f, "transform "); char tops[3] = { 't', 's', 'r' }; for (size_t op = 0; op < TRANSFORM_OPS_N; op++) { fprintf(f, "%c = (", tops[op]); for (uint8_t i = 0; i < 3; i++) { if (i) fprintf(f, " "); if (node->transform.has_op[op][i]) print_expr(f, &node->transform.op[op][i]); else fprintf(f, "_"); } fprintf(f, ") "); } fprintf(f, "\n"); for (size_t i = 0; i < node->transform.children.len; i++) print_node(f, &node->transform.children.ptr[i], stage, indent+1); break; } case NODE_OBJECT: fprintf(f, "object "); if (stage >= SCENE_LOADED) { fprintf(f, "#%"PRImesh_id" ", node->object.mesh.id); } else { switch (node->object.mesh.source.type) { case MESH_CUBE: fprintf(f, "cube "); break; case MESH_OBJ: fprintf(f, "obj %.*s ", PSTR(node->object.mesh.source.path.str)); break; } } print_surface(f, &node->object.surface, stage); fprintf(f, "\n"); break; case NODE_CAMERA: fprintf(f, "camera target="); switch (node->camera.target.type) { case POS_ABSOLUTE: fprintf(f, "("); for (size_t i = 0; i < 3; i++) { if (i) fprintf(f, " "); print_expr(f, &node->camera.target.absolute[i]); } fprintf(f, ") "); break; case POS_ATTACHED: if (stage >= SCENE_BOUND) fprintf(f, "(attach %p) ", node->camera.target.attach); else fprintf(f, "(attach %.*s) ", PSTR(node->camera.target.attach_name.str)); break; } fprintf(f, "roll=%d\n", node->camera.roll); break; case NODE_BONE: fprintf(f, "bone\n"); break; case NODE_LIGHT: fprintf(f, "todo light\n"); break; } } void print_scene(FILE *f, struct scene *scene, enum scene_stage stage) { fprintf(f, "scene stage="); switch (stage) { case SCENE_PARSED: fprintf(f, "parsed"); break; case SCENE_BOUND: fprintf(f, "bound"); break; case SCENE_LOADED: fprintf(f, "loaded"); break; } fprintf(f, "\n"); fprintf(f, INDENT"fps = %u\n", scene->fps); fprintf(f, INDENT"size = %u x %u\n", scene->size[0], scene->size[1]); fprintf(f, INDENT"outfile = %.*s\n", PSTR(scene->outfile)); fprintf(f, INDENT"seq = "); print_seq(f, scene->seq.len, scene->seq.ptr, stage); fprintf(f, "\n"); fprintf(f, INDENT"proj = "); switch (scene->proj.type) { case PROJ_PERSPECTIVE: fprintf(f, "perspective (fov = "); print_expr(f, &scene->proj.perspective.fov); fprintf(f, ") (planes = %f %f)\n", scene->proj.perspective.planes[0], scene->proj.perspective.planes[1]); break; case PROJ_ORTHO: fprintf(f, "persective (planes ="); for (size_t i = 0; i < 6; i++) fprintf(f, " %f", scene->proj.ortho.planes[i]); fprintf(f, ")\n"); break; } if (stage >= SCENE_BOUND) fprintf(f, INDENT"camera = %p\n", scene->camera); fprintf(f, INDENT"bg = "); if (scene->bg.present) print_surface(f, &scene->bg.data, stage); else fprintf(f, "transparent"); fprintf(f, "\n"); fprintf(f, INDENT"live = "); if (scene->live.present) fprintf(f, "%f\n", scene->live.data); else fprintf(f, "no\n"); print_node(f, &scene->root, stage, 1); fprintf(f, "\n"); }