summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/con_.c26
-rw-r--r--src/con_.h3
-rw-r--r--src/engineapi.c18
-rw-r--r--src/engineapi.h11
-rw-r--r--src/sst.c9
5 files changed, 37 insertions, 30 deletions
diff --git a/src/con_.c b/src/con_.c
index fd5db62..715872b 100644
--- a/src/con_.c
+++ b/src/con_.c
@@ -22,6 +22,7 @@
#include "abi.h"
#include "con_.h"
+#include "engineapi.h" // only for factories - XXX: do we care this is circular?
#include "extmalloc.h"
#include "gametype.h"
#include "mem.h"
@@ -52,6 +53,8 @@ void (*_con_colourmsgf)(void *this, const struct con_colour *c, const char *fmt,
// XXX: the const and non-const entries might actually be flipped on windows,
// not 100% sure, but dunno if it's worth essentially duping most of these when
// the actual executed machine code is probably identical anyway.
+// XXX: make these use gamedata at some point and avoid all the conditionals,
+// now that gamedata is populated before the rest of console init
DECL_VFUNC(int, AllocateDLLIdentifier, 5)
DECL_VFUNC(int, AllocateDLLIdentifier_p2, 8)
DECL_VFUNC(void, RegisterConCommand, 6, /*ConCommandBase*/ void *)
@@ -240,6 +243,7 @@ static void VCALLCONV InternalSetIntValue(struct con_var *this, int v) {
// Hack: IConVar things get this-adjusted pointers, we just reverse the offset
// to get the top pointer.
+// XXX: rewrite these at some point to use the normal VCALL stuff
static void VCALLCONV SetValue_str_thunk(void *thisoff, const char *v) {
struct con_var *this = mem_offset(thisoff,
-offsetof(struct con_var, vtable_iconvar));
@@ -335,7 +339,7 @@ void *_con_vtab_iconvar[7] = {
#endif
};
-static void fillvts(void) {
+void con_init(void) {
void **pc = _con_vtab_cmd + 3 + NVDTOR, **pv = _con_vtab_var + 3 + NVDTOR,
**pi = _con_vtab_iconvar
#ifndef _WIN32
@@ -394,6 +398,8 @@ static void fillvts(void) {
*pi++ = (void *)&IsFlagSet_thunk;
// last one: not in 004, but doesn't matter. one less branch!
*pi++ = (void *)&GetSplitScreenPlayerSlot;
+
+ regcmds();
}
void con_reg(void *cmd_or_var) {
@@ -405,9 +411,9 @@ void con_reg(void *cmd_or_var) {
}
}
-bool con_init(void *(*f)(const char *, int *), int plugin_ver) {
+bool con_detect(int pluginver) {
int ifacever; // for error messages
- if (_con_iface = f("VEngineCvar007", 0)) {
+ if (_con_iface = factory_engine("VEngineCvar007", 0)) {
// GENIUS HACK (BUT STILL BAD): Portal 2 has everything in ICvar shifted
// down 3 places due to the extra stuff in IAppSystem. This means that
// if we look up the Portal 2-specific cvar using FindCommandBase, it
@@ -442,28 +448,24 @@ bool con_init(void *(*f)(const char *, int *), int plugin_ver) {
ifacever = 7;
goto e;
}
- fillvts();
- regcmds();
return true;
}
- if (_con_iface = f("VEngineCvar004", 0)) {
+ if (_con_iface = factory_engine("VEngineCvar004", 0)) {
// TODO(compat): are there any cases where 004 is incompatible? could
// this crash? find out!
_con_colourmsgf = VFUNC(_con_iface, ConsoleColorPrintf_004);
dllid = VCALL(_con_iface, AllocateDLLIdentifier);
// even more spaghetti! we need the plugin interface version to
// accurately distinguish 2007/2013 branches
- if (plugin_ver == 3) _gametype_tag |= _gametype_tag_2013;
+ if (pluginver == 3) _gametype_tag |= _gametype_tag_2013;
else _gametype_tag |= _gametype_tag_OrangeBox;
- fillvts();
- regcmds();
return true;
}
- if (f("VEngineCvar003", 0)) {
+ if (factory_engine("VEngineCvar003", 0)) {
ifacever = 3;
goto warnoe;
}
- if (f("VEngineCvar002", 0)) {
+ if (factory_engine("VEngineCvar002", 0)) {
// I don't suppose there's anything below 002 worth caring about? Shrug.
ifacever = 2;
warnoe: con_warn("sst: error: old engine console support is not implemented\n");
@@ -474,7 +476,7 @@ warnoe: con_warn("sst: error: old engine console support is not implemented\n");
e: con_msg("\n\n");
con_msg("-- Please include ALL of the following if asking for help:\n");
con_msg("-- plugin: " LONGNAME " v" VERSION "\n");
- con_msg("-- interfaces: %d/%d\n", plugin_ver, ifacever);
+ con_msg("-- interfaces: %d/%d\n", pluginver, ifacever);
con_msg("\n\n");
return false;
}
diff --git a/src/con_.h b/src/con_.h
index 93306ad..900e8fa 100644
--- a/src/con_.h
+++ b/src/con_.h
@@ -94,7 +94,8 @@ typedef int (*con_complcb)(const char *part,
* These are called by the plugin load/unload functions; they have no use
* elsewhere.
*/
-bool con_init(void *(*f)(const char *, int *), int plugin_ver);
+bool con_detect(int pluginver);
+void con_init(void);
void con_disconnect(void);
/*
diff --git a/src/engineapi.c b/src/engineapi.c
index 5113883..369bebd 100644
--- a/src/engineapi.c
+++ b/src/engineapi.c
@@ -17,8 +17,10 @@
#include <stdbool.h> // used in generated code
#include <string.h> // "
+#include "con_.h"
#include "engineapi.h"
#include "gamedata.h"
+#include "gameinfo.h"
#include "gametype.h"
#include "intdefs.h"
#include "mem.h" // "
@@ -26,8 +28,6 @@
#include "vcall.h"
#include "x86.h"
-#include "con_.h"
-
u64 _gametype_tag = 0; // declared in gametype.h but seems sensible enough here
ifacefactory factory_client = 0, factory_server = 0, factory_engine = 0,
@@ -45,7 +45,9 @@ DECL_VFUNC_DYN(int, GetEngineBuildNumber)
#include <entpropsinit.gen.h>
-void engineapi_init(void) {
+bool engineapi_init(int pluginver) {
+ if (!con_detect(pluginver)) return false;
+
if (engclient = factory_engine("VEngineClient015", 0)) {
_gametype_tag |= _gametype_tag_Client015;
}
@@ -77,6 +79,11 @@ void engineapi_init(void) {
_gametype_tag |= _gametype_tag_SrvDLL005;
}
+ // detect p1 for the benefit of specific features
+ if (!GAMETYPE_MATCHES(Portal2) && con_findcmd("upgrade_portalgun")) {
+ _gametype_tag |= _gametype_tag_Portal1;
+ }
+
// TERRIBLE HACK: TODO(compat): come up with a better method later
if (GAMETYPE_MATCHES(L4D2) && os_access(OS_LIT(
"update/maps/c14m1_junkyard.bsp"), R_OK) != -1) {
@@ -86,12 +93,15 @@ void engineapi_init(void) {
// need to do this now; ServerClass network table iteration requires
// SendProp offsets
gamedata_init();
+ con_init();
+ if (!gameinfo_init()) { con_disconnect(); return false; }
- // TODO(compat): we need this terrible hack for now because TLS somehow
if (has_vtidx_GetAllServerClasses && has_sz_SendProp &&
has_off_SP_varname && has_off_SP_offset) {
initentprops(VCALL(srvdll, GetAllServerClasses));
}
+
+ return true;
}
// vi: sw=4 ts=4 noet tw=80 cc=80
diff --git a/src/engineapi.h b/src/engineapi.h
index 6def65b..fc191ca 100644
--- a/src/engineapi.h
+++ b/src/engineapi.h
@@ -127,13 +127,14 @@ extern void *globalvars;
/*
* Called on plugin init to attempt to initialise various core interfaces.
- * Doesn't return an error result, because the plugin can still load even if
- * this stuff is missing.
+ * This includes console/cvar initialisation and populating gametype and
+ * gamedata values.
*
- * Also performs additional gametype detection after con_init(), and calls
- * gamedata_init() to setup offsets and such.
+ * Returns true if there is enough stuff in place for the plugin to function -
+ * there may still be stuff missing. Returns false if there's no way the plugin
+ * can possibly work, e.g. if there's no cvar interface.
*/
-void engineapi_init(void);
+bool engineapi_init(int pluginver);
#endif
diff --git a/src/sst.c b/src/sst.c
index 13e8b19..5a7ca31 100644
--- a/src/sst.c
+++ b/src/sst.c
@@ -28,7 +28,6 @@
#include "ent.h"
#include "fov.h"
#include "fixes.h"
-#include "gamedata.h"
#include "gameinfo.h"
#include "gametype.h"
#include "hook.h"
@@ -201,13 +200,7 @@ static bool already_loaded = false, skip_unload = false;
static bool do_load(ifacefactory enginef, ifacefactory serverf) {
factory_engine = enginef; factory_server = serverf;
- if (!con_init(enginef, ifacever)) return false;
- engineapi_init(); // load some other interfaces. also calls gamedata_init()
- // detect p1 for the benefit of specific features
- if (!GAMETYPE_MATCHES(Portal2) && con_findcmd("upgrade_portalgun")) {
- _gametype_tag |= _gametype_tag_Portal1;
- }
- if (!gameinfo_init()) { con_disconnect(); return false; }
+ if (!engineapi_init(ifacever)) return false;
const void **p = vtable_firstdiff;
if (GAMETYPE_MATCHES(Portal2)) *p++ = (void *)&nop_p_v; // ClientFullyConnect