diff options
author | 2025-03-10 02:37:19 +0000 | |
---|---|---|
committer | 2025-04-06 16:41:13 +0100 | |
commit | 244fea664121acf12871ab5858a5fe95a2606b52 (patch) | |
tree | e42b1990ef97adc0f0ab48b9be7e11de7fee0558 /src/sst.c | |
parent | d86b7b41453c69b3854baa7cdc05a79a3cdfe092 (diff) | |
download | sst-244fea664121acf12871ab5858a5fe95a2606b52.tar.gz sst-244fea664121acf12871ab5858a5fe95a2606b52.zip |
Rewrite and redesign codegen and feature system
Also switch to somewhat proper C23 flags while we're at it.
This is a huge change. It took me forever, in between being really busy.
Sorry about that. But the good news is I'm now free to start integrating
the various patches that have accumulated since last release. Well, at
least in between still being really busy. Gotta manage expectations.
The main benefit of introducing GAMESPECIFIC() is that features
that don't apply to a particular game no longer show up *at all*, and
less time is wasted on init. It also enables a cool optimisation wherein
unnecessary REQUIRE_GAMEDATA() checks can elided at compile time
whenever the gamedata is known up-front to always exist in supported
games.
The DEF_FEAT_CVAR macro family meanwhile makes it easier to manage the
lifecycle of cvars/ccmds, with less manual registering, unhiding and
such.
Originally I was going to try and just hack these features into the
existing codegen abomination, but it just got too terrible. This rewrite
should make it easier to continue tweaking codegen behaviour in future.
It also has slightly better error messages.
Diffstat (limited to 'src/sst.c')
-rw-r--r-- | src/sst.c | 38 |
1 files changed, 30 insertions, 8 deletions
@@ -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 @@ -28,6 +28,8 @@ #include "engineapi.h" #include "errmsg.h" #include "event.h" +#include "extmalloc.h" // for freevars() in generated code +#include "feature.h" #include "fixes.h" #include "gamedata.h" #include "gameinfo.h" @@ -239,7 +241,7 @@ DEF_CCMD_HERE(sst_printversion, "Display plugin version information", 0) { // cvar to the top of the demo. this will be removed later, once there's a less // stupid way of achieving the same goal. #if VERSION_MAJOR != 0 || VERSION_MINOR != 9 -#error Need to change this manually, since codegen requires it to be spelled \ +#error Need to change this manually, since gluegen requires it to be spelled \ out in DEF_CVAR - better yet, can we get rid of this yet? #endif DEF_CVAR(__sst_0_9_beta, "", 0, CON_HIDDEN | CON_DEMO) @@ -271,7 +273,28 @@ static const char *updatenotes = "\ * More behind-the-scenes changes, as always\n\ "; -#include <featureinit.gen.h> // generated by build/codegen.c +enum { // used in generated code, must line up with + REQFAIL = _FEAT_INTERNAL_STATUSES, + NOGD, + NOGLOBAL +}; +static const char *const featmsgs[] = { // " + " [ OK! ] %s\n", + " [ FAILED! ] %s (error in initialisation)\n", + " [ unsupported ] %s (incompatible with this game or engine)\n", + " [ skipped ] %s (requires another feature)\n", + " [ unsupported ] %s (missing required gamedata entry)\n", + " [ FAILED! ] %s (failed to access engine)\n" +}; + +static inline void successbanner(void) { // called by generated code + con_colourmsg(&(struct rgba){64, 255, 64, 255}, + LONGNAME " v" VERSION " successfully loaded"); + con_colourmsg(&(struct rgba){255, 255, 255, 255}, " for game "); + con_colourmsg(&(struct rgba){0, 255, 255, 255}, "%s\n", gameinfo_title); +} + +#include <glue.gen.h> // generated by build/gluegen.c static void do_featureinit(void) { engineapi_lateinit(); @@ -297,7 +320,7 @@ static void do_featureinit(void) { "InputSystemVersion001", 0))) { errmsg_warnx("missing input system interface"); } - // ... and now for the real magic! + // ... and now for the real magic! (n.b. this also registers feature cvars) initfeatures(); // if we're autoloaded and the external autoupdate script downloaded a new @@ -374,7 +397,7 @@ static con_cmdcb orig_plugin_load_cb, orig_plugin_unload_cb; static int ownidx; // XXX: super hacky way of getting this to do_unload() static bool ispluginv1(const struct CPlugin *plugin) { - // basename string is set with strncmp(), so if there's null bytes with more + // basename string is set with strncpy(), so if there's null bytes with more // stuff after, we can't be looking at a v2 struct. and we expect null bytes // in ifacever, since it's a small int value return (plugin->v2.basename[0] == 0 || plugin->v2.basename[0] == 1) && @@ -437,6 +460,7 @@ static bool do_load(ifacefactory enginef, ifacefactory serverf) { *p++ = (void *)&nop_ipipp_v; // OnQueryCvarValueFinished (002+) *p++ = (void *)&nop_p_v; // OnEdictAllocated *p = (void *)&nop_p_v; // OnEdictFreed + preinitfeatures(); if (!deferinit()) { do_featureinit(); fixes_apply(); } if_hot (pluginhandler) { cmd_plugin_load = con_findcmd("plugin_load"); @@ -468,6 +492,7 @@ static void do_unload(void) { } endfeatures(); con_disconnect(); + freevars(); } static bool VCALLCONV Load(void *this, ifacefactory enginef, @@ -547,7 +572,4 @@ export const void *CreateInterface(const char *name, int *ret) { return 0; } -// no better place to put this lol -#include <evglue.gen.h> // generated by src/build/codegen.c - // vi: sw=4 ts=4 noet tw=80 cc=80 |