diff options
author | 2025-09-29 23:11:55 +0100 | |
---|---|---|
committer | 2025-10-01 21:37:26 +0100 | |
commit | b3c359826ae519ea2816128dfe641032b9e9e97f (patch) | |
tree | 065368fa828bbfc45ceddc58ef10dd82e02a3698 /src/con_.h | |
parent | 88f12ae363758c9214942335b4cdb4b5c0e559c9 (diff) | |
download | sst-b3c359826ae519ea2816128dfe641032b9e9e97f.tar.gz sst-b3c359826ae519ea2816128dfe641032b9e9e97f.zip |
While we're at it, come up with a way for certain gamedata matches to be
Windows-only. Somewhat reduces ifdef usage, although does not entirely
remove it of course.
Tested in HL2 2707. Haven't tested other HL2 builds, or Episode 1.
Doesn't seem to work in DMoMM yet either; not sure why.
A big list of stuff still to fix follows.
Hidden cvars are currently an issue. We still need to figure out what to
do with the flag bits because FCVAR_HIDDEN just doesn't exist in OE and
there's some other flag with the same value instead.
We also need to do something about the flag setting in fixes.c since
HIDDEN is again not a thing, and also DEVONLY is not a thing either.
When the plugin is autoloaded, all the initial log text gets eaten,
because there's some stupid crap we have to do to trick the engine into
displaying coloured text otherwise it just won't. Not even stuff from
Warning(). Very stupid, but Hayden already figured out a solution, so
that'll be done in another upcoming commit.
Apparently raw mouse input breaks the menu. We might need to bump up the
priority on making that hook only be active when there's no UI open -
something I wanted to do anyway due to the demo drive issues.
Big thanks to Hayden for doing a lot of the initial groundwork on this,
particularly the cvar registration stuff. He gets a copyright notice in
con_.c even though I ended up doing a lot of stuff differently because
quite a bit of his work is still in there.
Don't blame him for the self-modifying code though, that was my crazy
idea. Sorry, but, in my defence... Well, it works.
Diffstat (limited to 'src/con_.h')
-rw-r--r-- | src/con_.h | 38 |
1 files changed, 23 insertions, 15 deletions
@@ -134,7 +134,7 @@ struct con_var_common { struct con_var { // ConVar in engine struct con_cmdbase base; union { - struct con_var_common v1; + struct con_var_common v1; // OE struct { void **vtable_iconvar; // IConVar in engine (pure virtual) struct con_var_common v2; @@ -152,7 +152,6 @@ struct con_var { // ConVar in engine /* The change callback used in most branches of Source. Takes an IConVar :) */ typedef void (*con_varcb)(void *v, const char *, float); - /* Returns a registered variable with the given name, or null if not found. */ struct con_var *con_findvar(const char *name); @@ -164,9 +163,7 @@ struct con_cmd *con_findcmd(const char *name); * offset of which varies by engine version. This sub-struct contains * essentially all the actual cvar-specific data. */ -static inline struct con_var_common *con_getvarcommon(struct con_var *v) { - return &v->v2; -} +struct con_var_common *con_getvarcommon(const struct con_var *v); /* * These functions get and set the values of console variables in a @@ -196,36 +193,45 @@ con_cmdcbv1 con_getcmdcbv1(const struct con_cmd *cmd); * respectively. They are aliases to direct tier0 calls, so they work early on * even before anything else is initialised. */ -#if defined(__GNUC__) || defined(__clang__) #ifdef _WIN32 -#define __asm(x) __asm("_" x) // stupid mangling meme, only on windows! -#endif +void con_msg(const char *fmt, ...) _CON_PRINTF(1, 2) __asm("_Msg"); +void con_warn(const char *fmt, ...) _CON_PRINTF(1, 2) __asm("_Warning"); +#else void con_msg(const char *fmt, ...) _CON_PRINTF(1, 2) __asm("Msg"); void con_warn(const char *fmt, ...) _CON_PRINTF(1, 2) __asm("Warning"); -#undef __asm -#else -#error Need an equivalent of asm names for your compiler! #endif struct rgba; // in engineapi.h - forward declare here to avoid warnings struct ICvar; // " +// DO NOT CALL THIS DIRECTLY UNDER ANY CIRCUMSTANCES. void _con_colourmsg(void *dummy, const struct rgba *c, const char *fmt, ...) _CON_PRINTF(3, 4); + /* * This provides the same functionality as ConColorMsg which was removed from * tier0 in the L4D engine branch - specifically, it allows printing a message * with an arbitrary RGBA colour. It must only be used after a successful * con_init() call. */ -#define con_colourmsg(...) do { \ +#define con_colourmsg(/*c, fmt, */...) do { \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma("GCC diagnostic ignored \"-Wunused\"") \ /* intentionally uninitialised value allows the compiler to just create a - * hole in the stack without actually writing anything. this has been - * confirmed by looking at the asm, because I'm that type of weirdo :^) */ \ + hole in the stack without actually writing anything. this has been + confirmed by looking at the asm, because I'm that type of weirdo :^) */ \ void *_dummy; \ + /* we also have to reserve EBX as a register that our wrapper can clobber + but the callee (engine function) won't (as it's normally callee-save). + the way we do this is by marking the register as clobbered both before + and after the call and tying both to the lifetime of a dummy variable. + this ensures anything that'd otherwise get put in ebx is spilled + elsewhere until after the call has returned. */ \ + register uint _ebx __asm("ebx"); \ + __asm volatile ("" : "=r" (_ebx)); \ _con_colourmsg(_dummy, __VA_ARGS__); \ + __asm volatile ("" : "=r" (_ebx)); \ _Pragma("GCC diagnostic pop") \ } while (0) @@ -407,7 +413,9 @@ extern struct _con_vtab_iconvar_wrap { static void (*orig_##name##_cb)(int argc, const char *const *argv); \ static void _hook_##name##_cb(int argc, const char *const *argv); \ static void _hook_##name##_cbv1() { \ - _hook_##name##_cb(0, 0); /* XXX: ??? */ \ + extern int *_con_argc; \ + extern const char *(*_con_argv)[80]; \ + _hook_##name##_cb(*_con_argc, *_con_argv); \ } \ static void _hook_##name##_cbv2(const struct con_cmdargs *args) { \ _hook_##name##_cb(args->argc, args->argv); \ |