diff options
| -rw-r--r-- | TODO/compat | 2 | ||||
| -rw-r--r-- | gamedata/engine.kv | 9 | ||||
| -rw-r--r-- | src/con_.c | 1 | ||||
| -rw-r--r-- | src/engineapi.c | 3 | ||||
| -rw-r--r-- | src/engineapi.h | 2 | ||||
| -rw-r--r-- | src/fov.c | 1 | ||||
| -rw-r--r-- | src/sst.c | 50 | 
7 files changed, 34 insertions, 34 deletions
diff --git a/TODO/compat b/TODO/compat index 08d7c7f..7f210e8 100644 --- a/TODO/compat +++ b/TODO/compat @@ -1,5 +1,3 @@  Support more games and engine branches  ====  Pretty self-explanatory. - -*Alert! It seems Portal 2 had some stuff broken! Fix before 1.0 release!* diff --git a/gamedata/engine.kv b/gamedata/engine.kv index fdc03ff..72243b4 100644 --- a/gamedata/engine.kv +++ b/gamedata/engine.kv @@ -86,6 +86,13 @@ off_SP_offset {  }  // IEngineVGuiInternal/CEngineVGui -vtidx_VGuiConnect "3 + NVDTOR" // note: real name is Connect, way too generic +vtidx_VGuiConnect { // note: the actual name is Connect() but that's too generic +	default "3 + NVDTOR" +	Portal2 "4 + NVDTOR" // ActivateGameUI added +} +vtidx_VGuiIsInitialized { // likewise, function is just called IsInitialized() +	default "6 + NVDTOR" +	Portal2 "7 + NVDTOR" +}  // vi: sw=4 ts=4 noet tw=80 cc=80 ft=plain @@ -329,7 +329,6 @@ void con_reg(void *cmd_or_var) {  }  void con_init(void) { -	// FIXME: ConsoleColorPrintf isn't working in Portal 2, possible regression?  	_con_colourmsgf = VFUNC(_con_iface, ConsoleColorPrintf);  	dllid = AllocateDLLIdentifier(_con_iface); diff --git a/src/engineapi.c b/src/engineapi.c index b2272f9..0511c7d 100644 --- a/src/engineapi.c +++ b/src/engineapi.c @@ -40,7 +40,7 @@ struct VEngineServer *engserver;  DECL_VFUNC(void *, GetGlobalVars, 1)  void *globalvars; -void *inputsystem; +void *inputsystem, *vgui;  DECL_VFUNC_DYN(void *, GetAllServerClasses) @@ -74,6 +74,7 @@ bool engineapi_init(int pluginver) {  	if (pim) globalvars = GetGlobalVars(pim);  	inputsystem = factory_inputsystem("InputSystemVersion001", 0); +	vgui = factory_engine("VEngineVGui001", 0);  	void *srvdll;  	// TODO(compat): add this back when there's gamedata for 009 (no point atm) diff --git a/src/engineapi.h b/src/engineapi.h index 6394ec2..05f47ea 100644 --- a/src/engineapi.h +++ b/src/engineapi.h @@ -124,7 +124,7 @@ struct ServerClass {  extern struct VEngineClient *engclient;  extern struct VEngineServer *engserver;  extern void *globalvars; -extern void *inputsystem; +extern void *inputsystem, *vgui;  /*   * Called on plugin init to attempt to initialise various core interfaces. @@ -1,5 +1,6 @@  /*   * Copyright © 2022 Michael Smith <mikesmiffy128@gmail.com> + * Copyright © 2022 Willian Henrique <wsimanbrazil@yahoo.com.br>   *   * Permission to use, copy, modify, and/or distribute this software for any   * purpose with or without fee is hereby granted, provided that the above @@ -211,15 +211,17 @@ static void do_featureinit(void) {  	}  } -static void *vgui; -typedef void (*VCALLCONV VGuiConnect_func)(void); +typedef void (*VCALLCONV VGuiConnect_func)(void *this);  static VGuiConnect_func orig_VGuiConnect; -static void VCALLCONV hook_VGuiConnect(void) { -	orig_VGuiConnect(); +static void VCALLCONV hook_VGuiConnect(void *this) { +	orig_VGuiConnect(this);  	do_featureinit(); -	unhook_vtable(*(void ***)vgui, vtidx_VGuiConnect, (void *)orig_VGuiConnect); +	unhook_vtable(*(void ***)vgui, vtidx_VGuiConnect, +			(void *)orig_VGuiConnect);  } +DECL_VFUNC_DYN(bool, VGuiIsInitialized) +  // --- Magical deferred load order hack nonsense! ---  // The engine loads VDF plugins basically right after server.dll, but long  // before most other stuff, which makes hooking certain other stuff a pain. We @@ -227,23 +229,22 @@ static void VCALLCONV hook_VGuiConnect(void) {  // in before config.cfg, which is needed for any kind of configuration to work  // correctly.  // -// So here, we hook CEngineVGui::Connect() which is pretty much the last thing -// that gets called on init, and defer feature init till afterwards. That allows -// us to touch pretty much any engine stuff without worrying about load order -// nonsense. -// -// In do_load() below, we check to see whether we're loading early by checking -// whether gameui.dll is loaded yet; this is one of several possible arbitrary -// checks. If it's loaded already, we assume we're getting loaded late via the -// console and just init everything immediately. +// So here, we hook CEngineVGui::Connect() which is one the very last things +// to get called on startup, and use that hook to defer feature init till after +// most of the rest of the game is up and running. That allows us to touch +// pretty much any engine stuff without worrying about load order nonsense.  //  // Route credit to Bill for helping figure a lot of this out - mike -static void deferinit(void) { -	vgui = factory_engine("VEngineVGui001", 0); +static bool deferinit(void) {  	if (!vgui) { -		errmsg_warnx("couldn't get VEngineVGui for deferred feature setup"); +		errmsg_warnx("can't use VEngineVGui for deferred feature setup");  		goto e;  	} +	// Arbitrary check to infer whether we've been early- or late-loaded. +	// We used to just see whether gameui.dll/libgameui.so was loaded, but +	// Portal 2 does away with the separate gameui library, so now we just call +	// CEngineVGui::IsInitialized() which works everywhere. +	if (VGuiIsInitialized(vgui)) return false;  	if (!os_mprot(*(void ***)vgui + vtidx_VGuiConnect, sizeof(void *),  			PAGE_READWRITE)) {  		errmsg_warnsys("couldn't make CEngineVGui vtable writable for deferred " @@ -252,11 +253,11 @@ static void deferinit(void) {  	}  	orig_VGuiConnect = (VGuiConnect_func)hook_vtable(*(void ***)vgui,  			vtidx_VGuiConnect, (void *)&hook_VGuiConnect); -	return; +	return true;  e:	con_warn("!!! SOME FEATURES MAY BE BROKEN !!!\n"); -	// I think this is the lesser of two evils! Unlikely to happen anyway. -	do_featureinit(); +	// Lesser of two evils: just init features now. Unlikely to happen anyway. +	return false;  }  static bool do_load(ifacefactory enginef, ifacefactory serverf) { @@ -329,14 +330,7 @@ static bool do_load(ifacefactory enginef, ifacefactory serverf) {  		}  	} -#ifdef _WIN32 -	bool isvdf = !GetModuleHandleW(L"gameui.dll"); -#else -	void *gameuilib = dlopen("bin/libgameui.so", RTLD_NOW | RLTD_NOLOAD); -	bool isvdf = !gameuilib; -	if (gameuilib) dlclose(gameuilib); -#endif -	if (isvdf) deferinit(); else do_featureinit(); +	if (!deferinit()) do_featureinit();  	return true;  }  | 
