diff options
| author | 2025-12-26 23:12:11 +0000 | |
|---|---|---|
| committer | 2026-02-16 19:11:24 +0000 | |
| commit | af370088fc178996a46ee508aaa1a2c46318bbf2 (patch) | |
| tree | cf1f6c01ad7c101d3fd4abb44835d9deb600e30d /src/demorec.c | |
| parent | 40f9d989df2c1ff2f567656ccbdbfc0d97e34a77 (diff) | |
| download | sst-af370088fc178996a46ee508aaa1a2c46318bbf2.tar.gz sst-af370088fc178996a46ee508aaa1a2c46318bbf2.zip | |
Move to static trampolines and type-safe hooks
For some reason the DLL got a tiny little bit bigger again but that's
fine. This will make orig_ calls more efficient in the inline case, and
also make it harder to screw up and hook the wrong thing by mistake.
Self-explanatory-ish, apart from the fact it's a fairly large API change
of course. And it relies on some more bonkers assembler directive
hackery.
But it works!
The only complaint one might have is that the featsetup functions no
longer take an explicit string which occasionally yields slightly less
perfect error messages, but I've decided this isn't really a problem and
makes the API nicer to use. It's a tradeoff, innit.
Diffstat (limited to 'src/demorec.c')
| -rw-r--r-- | src/demorec.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/src/demorec.c b/src/demorec.c index 0511d46..6070bee 100644 --- a/src/demorec.c +++ b/src/demorec.c @@ -62,8 +62,9 @@ DEF_EVENT(DemoRecordStopped, int) struct CDemoRecorder; typedef void (*VCALLCONV SetSignonState_func)(struct CDemoRecorder *, int); -static SetSignonState_func orig_SetSignonState; -static void VCALLCONV hook_SetSignonState(struct CDemoRecorder *this, int state) { +DEF_VTABLE_HOOK(SetSignonState_func, SetSignonState) +static void VCALLCONV hookdest_SetSignonState(struct CDemoRecorder *this, + int state) { // NEW fires once every map or save load, but only bumps number if demo file // was left open (i.e. every transition). bump it unconditionally instead! if (state == SIGNONSTATE_NEW) { @@ -81,8 +82,8 @@ static void VCALLCONV hook_SetSignonState(struct CDemoRecorder *this, int state) } typedef void (*VCALLCONV StopRecording_func)(struct CDemoRecorder *); -static StopRecording_func orig_StopRecording; -static void VCALLCONV hook_StopRecording(struct CDemoRecorder *this) { +DEF_VTABLE_HOOK(StopRecording_func, StopRecording) +static void VCALLCONV hookdest_StopRecording(struct CDemoRecorder *this) { bool wasrecording = *recording; int lastnum = *demonum; orig_StopRecording(this); @@ -277,10 +278,8 @@ INIT { errmsg_errorx("couldn't find demo basename variable"); return FEAT_INCOMPAT; } - orig_SetSignonState = (SetSignonState_func)hook_vtable(vtable, - vtidx_SetSignonState, (void *)&hook_SetSignonState); - orig_StopRecording = (StopRecording_func)hook_vtable(vtable, - vtidx_StopRecording, (void *)&hook_StopRecording); + hook_SetSignonState(vtable, vtidx_SetSignonState, &hookdest_SetSignonState); + hook_StopRecording(vtable, vtidx_StopRecording, &hookdest_StopRecording); hook_record_cb(cmd_record); hook_stop_cb(cmd_stop); return FEAT_OK; @@ -291,8 +290,8 @@ END { // avoid dumb edge case if someone somehow records and immediately unloads if (*recording && *demonum == 0) *demonum = 1; void **vtable = demorecorder->vtable; - unhook_vtable(vtable, vtidx_SetSignonState, (void *)orig_SetSignonState); - unhook_vtable(vtable, vtidx_StopRecording, (void *)orig_StopRecording); + unhook_SetSignonState(vtable, vtidx_SetSignonState); + unhook_StopRecording(vtable, vtidx_StopRecording); unhook_record_cb(cmd_record); unhook_stop_cb(cmd_stop); } |
