diff options
Diffstat (limited to 'src/build/mkgamedata.c')
-rw-r--r-- | src/build/mkgamedata.c | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/src/build/mkgamedata.c b/src/build/mkgamedata.c index 1fce1cf..ed8cf97 100644 --- a/src/build/mkgamedata.c +++ b/src/build/mkgamedata.c @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Michael Smith <mikesmiffy128@gmail.com> + * Copyright © 2025 Michael Smith <mikesmiffy128@gmail.com> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -29,7 +29,7 @@ #endif static noreturn die(int status, const char *s) { - fprintf(stderr, "mkentprops: %s\n", s); + fprintf(stderr, "mkentprops: fatal: %s\n", s); exit(status); } @@ -156,7 +156,37 @@ static inline noreturn diewrite(void) { die(100, "couldn't write to file"); } _( "/* This file is autogenerated by src/build/mkgamedata.c. DO NOT EDIT! */") \ _( "") -static void decls(FILE *out) { +static inline void knowngames(FILE *out) { + // kind of tricky optimisation: if a gamedata entry has no default but + // does have game-specific values which match a feature's GAMESPECIFIC() + // macro, load-time conditional checks resulting from REQUIRE_GAMEDATA() can + // be elided at compile-time. + for (int i = 0, j; i < nents - 1; i = j) { + while (exprs[i]) { // if there's a default value, we don't need this + // skip to next unindented thing, return if there isn't one with at + // least one indented thing under it. + for (++i; indents[i] != 0; ++i) if (i == nents - 1) return; + } +F( "#line %d \"%" fS "\"", srclines[i], srcnames[srcfiles[i]]) + if (fprintf(out, "#define _GAMES_WITH_%s (", sbase + tags[i]) < 0) { + diewrite(); + } + const char *pipe = ""; + for (j = i + 1; j < nents && indents[j] != 0; ++j) { + // don't attempt to optimise for nested conditionals because that's + // way more complicated and also basically defeats the purpose. + if (indents[j] != 1) continue; + if (fprintf(out, "%s \\\n\t _gametype_tag_%s", pipe, + sbase + tags[j]) < 0) { + diewrite(); + } + pipe = " |"; + } + fputs(" \\\n)\n", out); + } +} + +static inline void decls(FILE *out) { for (int i = 0; i < nents; ++i) { if (indents[i] != 0) continue; F( "#line %d \"%" fS "\"", srclines[i], srcnames[srcfiles[i]]) @@ -175,13 +205,13 @@ F( "#line %d \"%" fS "\"", srclines[i], srcnames[srcfiles[i]]) if_cold (i == nents - 1 || !indents[i + 1]) { // no tags - it's constant F( "enum { %s = (%s) };", sbase + tags[i], sbase + exprs[i]) } - else { // global variable intialised by gamedata_init() call + else { // global variable intialised by initgamedata() call F( "extern int %s;", sbase + tags[i]); } } } -static void defs(FILE *out) { +static inline void defs(FILE *out) { for (int i = 0; i < nents; ++i) { if (indents[i] != 0) continue; if_hot (i < nents - 1 && indents[i + 1]) { @@ -196,8 +226,8 @@ F( "int %s = -2147483648;", sbase + tags[i]) } } -static void init(FILE *out) { -_( "void gamedata_init(void) {") +static inline void init(FILE *out) { +_( "static void initgamedata(void) {") int varidx; int indent = 0; for (int i = 0; i < nents; ++i) { @@ -261,6 +291,7 @@ int OS_MAIN(int argc, os_char *argv[]) { FILE *out = fopen(".build/include/gamedata.gen.h", "wb"); if (!out) die(100, "couldn't open gamedata.gen.h"); H(); + knowngames(out); decls(out); out = fopen(".build/include/gamedatainit.gen.h", "wb"); |