aboutsummaryrefslogtreecommitdiff
path: root/src/build/mkgamedata.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/build/mkgamedata.c')
-rw-r--r--src/build/mkgamedata.c45
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");