aboutsummaryrefslogtreecommitdiff
path: root/src/autojump.c
diff options
context:
space:
mode:
authorGravatar Michael Smith <mikesmiffy128@gmail.com> 2025-04-17 01:39:10 +0100
committerGravatar Michael Smith <mikesmiffy128@gmail.com> 2025-04-17 20:02:18 +0100
commit8a669bc96ffdb9d0f6f54e464da11e3375c80a55 (patch)
tree569dac0cd082ad25e779a69f0bcceff5ca212bb1 /src/autojump.c
parent0b40d4d9ea1cbfbb92795e0d6f26cf108f2dec5f (diff)
downloadsst-8a669bc96ffdb9d0f6f54e464da11e3375c80a55.tar.gz
sst-8a669bc96ffdb9d0f6f54e464da11e3375c80a55.zip
Add type-safety to virtual calls and accessors
This probably should have been the design from the start. It's still possible to use void pointers, and this is done in a couple of places for simplicity, but wherever possible, we have actual structs for things now. Additionally, in places where vtables are fiddled with, e.g. vtable hooks, we have actual struct definitions with vtable pointers so there's need for pointer-casting horror.
Diffstat (limited to 'src/autojump.c')
-rw-r--r--src/autojump.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/src/autojump.c b/src/autojump.c
index a8a21ca..6d0fbda 100644
--- a/src/autojump.c
+++ b/src/autojump.c
@@ -24,7 +24,6 @@
#include "hook.h"
#include "intdefs.h"
#include "langext.h"
-#include "mem.h"
#include "os.h"
#include "vcall.h"
@@ -33,20 +32,21 @@ REQUIRE_GAMEDATA(off_mv)
REQUIRE_GAMEDATA(vtidx_CheckJumpButton)
REQUIRE_GLOBAL(factory_client) // note: server will never be null
-DEF_ACCESSORS(struct CMoveData *, mv)
+struct CGameMovement { void **vtable; };
+DEF_ACCESSORS(struct CGameMovement, struct CMoveData *, mv)
-DEF_FEAT_CVAR(sst_autojump, "Jump upon hitting the ground while holding space", 0,
- CON_REPLICATE | CON_DEMO)
+DEF_FEAT_CVAR(sst_autojump, "Jump upon hitting the ground while holding space",
+ 0, CON_REPLICATE | CON_DEMO)
#define NIDX 256 // *completely* arbitrary lol
static bool justjumped[NIDX] = {0};
static inline int handleidx(ulong h) { return h & (1 << 11) - 1; }
-static void *gmsv = 0, *gmcl = 0;
-typedef bool (*VCALLCONV CheckJumpButton_func)(void *);
+static struct CGameMovement *gmsv = 0, *gmcl = 0;
+typedef bool (*VCALLCONV CheckJumpButton_func)(struct CGameMovement *);
static CheckJumpButton_func origsv, origcl;
-static bool VCALLCONV hooksv(void *this) {
+static bool VCALLCONV hooksv(struct CGameMovement *this) {
struct CMoveData *mv = get_mv(this);
int idx = handleidx(mv->playerhandle);
if (con_getvari(sst_autojump) && mv->firstrun && !justjumped[idx]) {
@@ -57,7 +57,7 @@ static bool VCALLCONV hooksv(void *this) {
return ret;
}
-static bool VCALLCONV hookcl(void *this) {
+static bool VCALLCONV hookcl(struct CGameMovement *this) {
struct CMoveData *mv = get_mv(this);
// FIXME: this will stutter in the rare case where justjumped is true.
// currently doing clientside justjumped handling makes multiplayer
@@ -68,9 +68,8 @@ static bool VCALLCONV hookcl(void *this) {
return justjumped[0] = origcl(this);
}
-static bool unprot(void *gm) {
- void **vtable = mem_loadptr(gm);
- bool ret = os_mprot(vtable + vtidx_CheckJumpButton, sizeof(void *),
+static bool unprot(struct CGameMovement *gm) {
+ bool ret = os_mprot(gm->vtable + vtidx_CheckJumpButton, sizeof(void *),
PAGE_READWRITE);
if (!ret) errmsg_errorsys("couldn't make virtual table writable");
return ret;
@@ -99,9 +98,9 @@ INIT {
return FEAT_FAIL;
}
if_cold (!unprot(gmcl)) return FEAT_FAIL;
- origsv = (CheckJumpButton_func)hook_vtable(*(void ***)gmsv,
+ origsv = (CheckJumpButton_func)hook_vtable(gmsv->vtable,
vtidx_CheckJumpButton, (void *)&hooksv);
- origcl = (CheckJumpButton_func)hook_vtable(*(void ***)gmcl,
+ origcl = (CheckJumpButton_func)hook_vtable(gmcl->vtable,
vtidx_CheckJumpButton, (void *)&hookcl);
if (GAMETYPE_MATCHES(Portal1)) {
@@ -119,8 +118,8 @@ INIT {
}
END {
- unhook_vtable(*(void ***)gmsv, vtidx_CheckJumpButton, (void *)origsv);
- unhook_vtable(*(void ***)gmcl, vtidx_CheckJumpButton, (void *)origcl);
+ unhook_vtable(gmsv->vtable, vtidx_CheckJumpButton, (void *)origsv);
+ unhook_vtable(gmcl->vtable, vtidx_CheckJumpButton, (void *)origcl);
}
// vi: sw=4 ts=4 noet tw=80 cc=80