From 464c9398ae49d8faae46f81fb7040155408858f7 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Wed, 30 Aug 2023 23:18:38 +0100 Subject: Perform very minor load/unload optimisations Because why not. --- src/ac.c | 1 + src/build/mkentprops.c | 10 +--------- src/demorec.c | 2 ++ src/engineapi.c | 14 +++++++++++--- src/engineapi.h | 6 ++++++ src/fov.c | 1 + src/portalcolours.c | 1 + src/rinput.c | 2 ++ src/sst.c | 24 +++++++++++------------- src/sst.h | 1 - 10 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/ac.c b/src/ac.c index 228fa58..be7fbba 100644 --- a/src/ac.c +++ b/src/ac.c @@ -430,6 +430,7 @@ e: munmap(keybox, 4096); END { ac_disable(); #if defined(_WIN32) + // TODO(opt): *maybe* do the skip-on-quit stuff here. feels a bit scary... WerUnregisterExcludedMemoryBlock(keybox); // this'd better not fail! VirtualFree(keybox, 4096, MEM_RELEASE); win32_end(); diff --git a/src/build/mkentprops.c b/src/build/mkentprops.c index fdb6982..9fb2a50 100644 --- a/src/build/mkentprops.c +++ b/src/build/mkentprops.c @@ -157,15 +157,7 @@ _( " const char *varname = mem_loadptr(mem_offset(p, off_SP_varname));") pp - c->props.data < c->props.sz; ++pp) { F( " %sif (!strcmp(varname, \"%s\")) {", else2, (*pp)->propname) F( " has_%s = true;", (*pp)->varname) - // from AM L4D2 SDK headers: - // > SENDPROP_VECTORELEM makes [offset] negative to start with so we - // > can detect that and set the SPROP_IS_VECTOR_ELEM flag. - // apparently if we're loaded via VDF, it hasn't been flipped back - // yet. just calling abs() on everything as an easy solution. - // TODO(opt): if we moved this into deferred init we wouldn't need - // to bother with this, but that might involve untangling more - // engineapi stuff -F( " %s = abs(*(int *)mem_offset(p, off_SP_offset));", +F( " %s = mem_load32(mem_offset(p, off_SP_offset));", (*pp)->varname) _( " if (!--needprops) break;") _( " }") diff --git a/src/demorec.c b/src/demorec.c index e728ca5..6e3b2ec 100644 --- a/src/demorec.c +++ b/src/demorec.c @@ -29,6 +29,7 @@ #include "mem.h" #include "os.h" #include "ppmagic.h" +#include "sst.h" #include "vcall.h" #include "x86.h" #include "x86util.h" @@ -289,6 +290,7 @@ INIT { } END { + if (!sst_userunloaded) return; // avoid dumb edge case if someone somehow records and immediately unloads if (*recording && *demonum == 0) *demonum = 1; void **vtable = *(void ***)demorecorder; diff --git a/src/engineapi.c b/src/engineapi.c index 24a2d6b..6cb67d2 100644 --- a/src/engineapi.c +++ b/src/engineapi.c @@ -47,6 +47,8 @@ DECL_VFUNC_DYN(void *, GetAllServerClasses) #include // generated by build/mkentprops.c +static void *srvdll; + bool engineapi_init(int pluginver) { if (!con_detect(pluginver)) return false; pluginhandler = factory_engine("ISERVERPLUGINHELPERS001", 0); @@ -75,7 +77,6 @@ bool engineapi_init(int pluginver) { vgui = factory_engine("VEngineVGui001", 0); - void *srvdll; // TODO(compat): add this back when there's gamedata for 009 (no point atm) /*if (srvdll = factory_engine("ServerGameDLL009", 0)) { _gametype_tag |= _gametype_tag_SrvDLL009; @@ -104,11 +105,18 @@ bool engineapi_init(int pluginver) { gamedata_init(); con_init(); if (!gameinfo_init()) { con_disconnect(); return false; } - if (has_vtidx_GetAllServerClasses && has_sz_SendProp && + return true; +} + +void engineapi_lateinit(void) { + // from AM L4D2 SDK headers: + // > SENDPROP_VECTORELEM makes [the offset] negative to start with so we + // > can detect that and set the SPROP_IS_VECTOR_ELEM flag. + // by doing this at the deferred stage, we avoid having to abs() everything + if (srvdll && has_vtidx_GetAllServerClasses && has_sz_SendProp && has_off_SP_varname && has_off_SP_offset) { initentprops(GetAllServerClasses(srvdll)); } - return true; } // vi: sw=4 ts=4 noet tw=80 cc=80 diff --git a/src/engineapi.h b/src/engineapi.h index fbc062b..e95e282 100644 --- a/src/engineapi.h +++ b/src/engineapi.h @@ -164,6 +164,12 @@ extern struct CServerPlugin *pluginhandler; */ bool engineapi_init(int pluginver); +/* + * Called right before deferred feature initialisation to set up some additional + * (nonessential) core stuff - currently this means entprops data. + */ +void engineapi_lateinit(void); + #endif // vi: sw=4 ts=4 noet tw=80 cc=80 fdm=marker diff --git a/src/fov.c b/src/fov.c index 1886c1f..7500064 100644 --- a/src/fov.c +++ b/src/fov.c @@ -118,6 +118,7 @@ INIT { } END { + if (!sst_userunloaded) return; if (real_fov_desired && real_fov_desired != fov_desired) { real_fov_desired->parent->maxval = 90; if (con_getvarf(real_fov_desired) > 90) { diff --git a/src/portalcolours.c b/src/portalcolours.c index 33a6020..0eb3a30 100644 --- a/src/portalcolours.c +++ b/src/portalcolours.c @@ -155,6 +155,7 @@ INIT { } END { + if (!sst_userunloaded) return; unhook_inline((void *)orig_UTIL_Portal_Color); } diff --git a/src/rinput.c b/src/rinput.c index 79b6661..6b61bff 100644 --- a/src/rinput.c +++ b/src/rinput.c @@ -29,6 +29,7 @@ #include "hook.h" #include "intdefs.h" #include "mem.h" +#include "sst.h" #include "vcall.h" FEATURE("scalable raw mouse input") @@ -217,6 +218,7 @@ e0: UnregisterClassW(L"RInput", 0); } END { + if (!sst_userunloaded) return; if (orig_SetCursorPos) { // if null, we didn't init our own implementation RAWINPUTDEVICE rd = { .dwFlags = RIDEV_REMOVE, diff --git a/src/sst.c b/src/sst.c index 3618210..6b03acf 100644 --- a/src/sst.c +++ b/src/sst.c @@ -250,6 +250,7 @@ static const char *updatenotes = "\ #include // generated by build/codegen.c static void do_featureinit(void) { + engineapi_lateinit(); // load libs that might not be there early (...at least on Linux???) clientlib = os_dlhandle(OS_LIT("client") OS_LIT(OS_DLSUFFIX)); if (!clientlib) { @@ -410,22 +411,19 @@ static bool do_load(ifacefactory enginef, ifacefactory serverf) { } static void do_unload(void) { -#ifdef _WIN32 // this is only relevant in builds that predate linux support - if (pluginhandler) { // if not, oh well too bad :^) + if (sst_userunloaded) { // note: pluginhandler must also be set here cmd_plugin_load->cb = orig_plugin_load_cb; cmd_plugin_unload->cb = orig_plugin_unload_cb; - if (sst_userunloaded) { - struct CPlugin **plugins = pluginhandler->plugins.m.mem; - // see comment in CPlugin above. setting this to the real handle - // right before the engine tries to unload us allows it to actually - // do so. in newer branches this is redundant but doesn't do any - // harm so it's just unconditional. NOTE: old engines ALSO just leak - // the handle and never call Unload() if Load() fails; can't really - // do anything about that. - plugins[ownidx]->module = ownhandle(); - } - } +#ifdef _WIN32 // this bit is only relevant in builds that predate linux support + struct CPlugin **plugins = pluginhandler->plugins.m.mem; + // see comment in CPlugin above. setting this to the real handle right + // before the engine tries to unload us allows it to actually do so. in + // newer branches this is redundant but doesn't do any harm so it's just + // unconditional. NOTE: old engines ALSO just leak the handle and never + // call Unload() if Load() fails; can't really do anything about that. + plugins[ownidx]->module = ownhandle(); #endif + } endfeatures(); con_disconnect(); } diff --git a/src/sst.h b/src/sst.h index f7e4bb4..43a56b7 100644 --- a/src/sst.h +++ b/src/sst.h @@ -33,7 +33,6 @@ extern void *clientlib; /* occasionally useful: quick query to determine how sst was loaded */ extern bool sst_earlyloaded; /* similar query for how we are being unloaded - ONLY valid during unload */ -// TODO(opt): we can skip a whole bunch of cleanup when exiting the game! extern bool sst_userunloaded; #endif -- cgit v1.2.3