summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMichael Smith <mikesmiffy128@gmail.com>2023-08-30 23:18:38 +0100
committerMichael Smith <mikesmiffy128@gmail.com>2023-08-30 23:44:50 +0100
commit464c9398ae49d8faae46f81fb7040155408858f7 (patch)
tree3c8f035e752124a7f9f32179fa01d5c56c9d2439
parent8a1c4de9b33128c10378f1938d8a60c071f01ad0 (diff)
Perform very minor load/unload optimisations
Because why not.
-rw-r--r--src/ac.c1
-rw-r--r--src/build/mkentprops.c10
-rw-r--r--src/demorec.c2
-rw-r--r--src/engineapi.c14
-rw-r--r--src/engineapi.h6
-rw-r--r--src/fov.c1
-rw-r--r--src/portalcolours.c1
-rw-r--r--src/rinput.c2
-rw-r--r--src/sst.c24
-rw-r--r--src/sst.h1
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 <entpropsinit.gen.h> // 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 <featureinit.gen.h> // 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