From 115020ba7a1230bbe4225e76e707423d0e8f6acc Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 13:33:14 +0200 Subject: [PATCH 01/12] added GetModuleAPI function for OpenJK entry point, identical to GetGameAPI --- src/main.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 69b1c97..cc6d10b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -124,17 +124,17 @@ cgameinfo cgame = { do is store the syscall, load the config file, and attempt to figure out what game engine we are in. This is either determined by the config file, or by getting the filename of the QMM DLL itself. */ -C_DLLEXPORT void dllEntry(eng_syscall syscall) { +C_DLLEXPORT void dllEntry(void* syscall) { // cgame passthrough hack: // QMM is already loaded, so this is a cgame passthrough situation. since the mod DLL isn't loaded yet, we can // just store the syscall pointer and pass it to the mod once it's loaded in vmMain(GAME_INIT) if (g_gameinfo.game) { - cgame.syscall = syscall; - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("QMM passthrough_syscall = {}\n", (void*)cgame.syscall); + cgame.syscall = (eng_syscall)syscall; + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("QMM passthrough_syscall = {}\n", syscall); return; } - main_handle_entry((void*)syscall, nullptr, false); // false = !is_GetGameAPI + main_handle_entry(syscall, nullptr, false); // false = !is_GetGameAPI return; } @@ -190,7 +190,13 @@ C_DLLEXPORT void dllEntry(eng_syscall syscall) { to the proper function pointer in the struct. */ C_DLLEXPORT void* GetGameAPI(void* import, void* extra) { - return main_handle_entry(import, extra, true); // true = is_GetGameAPI + return main_handle_entry(import, extra, true); // true = is_GetGameAPI +} + + +// this is the same as the 2-arg GetGameAPI but OpenJK renamed it +C_DLLEXPORT void* GetModuleAPI(void* import, void* extra) { + return main_handle_entry(import, extra, true); // true = is_GetGameAPI } From e3b4a477c0d81f756bd2b64e808d6a806dc5fd73 Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 13:33:50 +0200 Subject: [PATCH 02/12] check for a function named "GetModuleAPI" if "GetGameAPI" lookup fails --- src/mod.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mod.cpp b/src/mod.cpp index e5e98b4..02bd7ce 100644 --- a/src/mod.cpp +++ b/src/mod.cpp @@ -194,6 +194,10 @@ static bool s_mod_load_getgameapi(mod& mod) { // look for GetGameAPI function mod_GetGameAPI pfnGGA = (mod_GetGameAPI)dlsym(mod.dll, "GetGameAPI"); + // try for "GetModuleAPI", which is what OpenJK uses + if (!pfnGGA) + pfnGGA = (mod_GetGameAPI)dlsym(mod.dll, "GetModuleAPI"); + if (!pfnGGA) { LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): Unable to find \"GetGameAPI\" function\n", mod.path); goto fail; From f622bbcd7289b627dcd02a732bea2393ab557aa3 Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 13:35:07 +0200 Subject: [PATCH 03/12] if s_mod_load_getgameapi fails, fall back to s_mod_load_vmmain --- src/mod.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mod.cpp b/src/mod.cpp index 02bd7ce..aedc1a5 100644 --- a/src/mod.cpp +++ b/src/mod.cpp @@ -60,10 +60,14 @@ bool mod_load(mod& mod, std::string file) { return false; } + // pass off to engine-specific loading function + bool ret = false; if (g_gameinfo.game->funcs->pfnGetGameAPI) - return s_mod_load_getgameapi(mod); - else + ret = s_mod_load_getgameapi(mod); + + // fall back to vmmain loading if getgameapi failed + if (!ret) return s_mod_load_vmmain(mod); } From 4e29ef757501e08d264112ed10cbb077d84620c8 Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 17:03:27 +0200 Subject: [PATCH 04/12] have loading functions and vmmain/syscall for GetGameAPI systems. handle JAMP_mod_load based on how the game was loaded. --- src/game_jamp.cpp | 211 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 188 insertions(+), 23 deletions(-) diff --git a/src/game_jamp.cpp b/src/game_jamp.cpp index b2207d1..b8b5d59 100644 --- a/src/game_jamp.cpp +++ b/src/game_jamp.cpp @@ -22,14 +22,36 @@ Created By: GEN_QMM_MSGS(JAMP); GEN_EXTS(JAMP); -GEN_DLL(JAMP); +// store whether or not this mod was loaded as GetGameAPI or not +static bool s_is_GetGameAPI = false; + +// do not use macro since this game supports both dllEntry and GetGameAPI entry points +static const char* JAMP_eng_msg_names(intptr_t); +static const char* JAMP_mod_msg_names(intptr_t); +static bool JAMP_autodetect(bool, supportedgame*); +static intptr_t JAMP_syscall_legacy(intptr_t cmd, ...); +static intptr_t JAMP_vmMain_legacy(intptr_t cmd, ...); +static void JAMP_dllEntry(eng_syscall); +static intptr_t JAMP_syscall_GGA(intptr_t cmd, ...); +static intptr_t JAMP_vmMain_GGA(intptr_t cmd, ...); +static void* JAMP_GetGameAPI(void*, void*); +static bool JAMP_mod_load(void*); +static void JAMP_mod_unload(); +supportedgame_funcs JAMP_funcs = { + JAMP_qmm_eng_msgs, + JAMP_qmm_mod_msgs, + JAMP_eng_msg_names, + JAMP_mod_msg_names, + JAMP_autodetect, + nullptr, // JAMP_qvmsyscall + JAMP_dllEntry, + JAMP_GetGameAPI, + JAMP_mod_load, JAMP_mod_unload +}; // auto-detection logic for JAMP static bool JAMP_autodetect(bool is_GetGameAPI, supportedgame* game) { - if (is_GetGameAPI) - return false; - // QMM filename must match default or an OpenJK temp filename (if DLL was pulled from .pk3) if (!str_striequal(g_gameinfo.qmm_file, game->dllname) && !str_striequal(g_gameinfo.qmm_file.substr(0, 3), "ojk") @@ -39,26 +61,33 @@ static bool JAMP_autodetect(bool is_GetGameAPI, supportedgame* game) { if (!str_stristr(g_gameinfo.exe_file, "jamp") && !str_stristr(g_gameinfo.exe_file, "openjk.") && !str_stristr(g_gameinfo.exe_file, "openjkded")) return false; + // store how we were loaded + s_is_GetGameAPI = is_GetGameAPI; + return true; } // original syscall pointer that comes from the game engine -static eng_syscall orig_syscall = nullptr; +static eng_syscall orig_syscall_legacy = nullptr; // pointer to vmMain that comes from the mod -static mod_vmMain orig_vmMain = nullptr; +static mod_vmMain orig_vmMain_legacy = nullptr; + // wrapper syscall function that calls actual engine func from orig_import // this is how QMM and plugins will call into the engine -static intptr_t JAMP_syscall(intptr_t cmd, ...) { +static intptr_t JAMP_syscall_legacy(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); #ifdef _DEBUG if (cmd != G_PRINT) - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall({} {}) called\n", JAMP_eng_msg_names(cmd), cmd); + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall_legacy({} {}) called\n", JAMP_eng_msg_names(cmd), cmd); #endif + if (s_is_GetGameAPI) + return 0; + intptr_t ret = 0; switch (cmd) { @@ -69,8 +98,8 @@ static intptr_t JAMP_syscall(intptr_t cmd, ...) { static char buf[MAX_STRING_CHARS]; s = ""; int i = 1; - while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + while (i < orig_syscall_legacy(G_ARGC)) { + orig_syscall_legacy(G_ARGV, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -82,14 +111,14 @@ static intptr_t JAMP_syscall(intptr_t cmd, ...) { default: // all normal engine functions go to engine - ret = orig_syscall(cmd, QMM_PUT_SYSCALL_ARGS()); + ret = orig_syscall_legacy(cmd, QMM_PUT_SYSCALL_ARGS()); } // do anything that needs to be done after function call here #ifdef _DEBUG if (cmd != G_PRINT) - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall({} {}) returning {}\n", JAMP_eng_msg_names(cmd), cmd, ret); + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall_legacy({} {}) returning {}\n", JAMP_eng_msg_names(cmd), cmd, ret); #endif return ret; @@ -98,24 +127,27 @@ static intptr_t JAMP_syscall(intptr_t cmd, ...) { // wrapper vmMain function that calls actual mod func from orig_export // this is how QMM and plugins will call into the mod -static intptr_t JAMP_vmMain(intptr_t cmd, ...) { +static intptr_t JAMP_vmMain_legacy(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); #ifdef _DEBUG - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain({} {}) called\n", JAMP_mod_msg_names(cmd), cmd); + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain_legacy({} {}) called\n", JAMP_mod_msg_names(cmd), cmd); #endif - if (!orig_vmMain) + if (s_is_GetGameAPI) + return 0; + + if (!orig_vmMain_legacy) return 0; // store return value since we do some stuff after the function call is over intptr_t ret = 0; // all normal mod functions go to mod - ret = orig_vmMain(cmd, QMM_PUT_VMMAIN_ARGS()); + ret = orig_vmMain_legacy(cmd, QMM_PUT_VMMAIN_ARGS()); #ifdef _DEBUG - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain({} {}) returning {}\n", JAMP_mod_msg_names(cmd), cmd, ret); + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain_legacy({} {}) returning {}\n", JAMP_mod_msg_names(cmd), cmd, ret); #endif return ret; @@ -125,28 +157,161 @@ static intptr_t JAMP_vmMain(intptr_t cmd, ...) { static void JAMP_dllEntry(eng_syscall syscall) { LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_dllEntry({}) called\n", (void*)syscall); + // store how we were loaded + s_is_GetGameAPI = false; + // store original syscall from engine - orig_syscall = syscall; + orig_syscall_legacy = syscall; // pointer to wrapper vmMain function that calls actual mod vmMain func orig_vmMain - g_gameinfo.pfnvmMain = JAMP_vmMain; + g_gameinfo.pfnvmMain = JAMP_vmMain_legacy; // pointer to wrapper syscall function that calls actual engine syscall func - g_gameinfo.pfnsyscall = JAMP_syscall; + g_gameinfo.pfnsyscall = JAMP_syscall_legacy; LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_dllEntry({}) returning\n", (void*)syscall); } +// these variables are all for the GGA implementation for OpenJK, but can't add _GGA suffix +// to all because ROUTE_IMPORT/ROUTE_EXPORT macros use these names + +// a copy of the apiversion int that comes from the game engine +static intptr_t orig_apiversion_GGA = 0; + +// a copy of the original import struct that comes from the game engine +static game_import_t orig_import; + +// a copy of the original export struct pointer that comes from the mod +static game_export_t* orig_export = nullptr; + +// struct with lambdas that call QMM's syscall function. this is given to the mod +static game_import_t qmm_import = { + GEN_IMPORT(Print, G_PRINT), + // todo finish +}; + +// struct with lambdas that call QMM's vmMain function. this is given to the game engine +static game_export_t qmm_export = { + GEN_EXPORT(InitGame, GAME_INIT), + // todo finish +}; + + +// wrapper syscall function that calls actual engine func from orig_import +// this is how QMM and plugins will call into the engine +static intptr_t JAMP_syscall_GGA(intptr_t cmd, ...) { + QMM_GET_SYSCALL_ARGS(); + +#ifdef _DEBUG + if (cmd != G_PRINT) + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall_GGA({} {}) called\n", JAMP_eng_msg_names(cmd), cmd); +#endif + + if (!s_is_GetGameAPI) + return 0; + + intptr_t ret = 0; + + switch (cmd) { + ROUTE_IMPORT(Print, G_PRINT); + + default: + break; + }; + + // do anything that needs to be done after function call here + +#ifdef _DEBUG + if (cmd != G_PRINT) + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall_GGA({} {}) returning {}\n", JAMP_eng_msg_names(cmd), cmd, ret); +#endif + + return ret; +} + + +// wrapper vmMain function that calls actual mod func from orig_export +// this is how QMM and plugins will call into the mod +static intptr_t JAMP_vmMain_GGA(intptr_t cmd, ...) { + QMM_GET_VMMAIN_ARGS(); + +#ifdef _DEBUG + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain_GGA({} {}) called\n", JAMP_mod_msg_names(cmd), cmd); +#endif + + if (!s_is_GetGameAPI) + return 0; + + if (!orig_export) + return 0; + + // store return value since we do some stuff after the function call is over + intptr_t ret = 0; + + switch (cmd) { + ROUTE_EXPORT(InitGame, GAME_INIT); + + default: + break; + }; + +#ifdef _DEBUG + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain_GGA({} {}) returning {}\n", JAMP_mod_msg_names(cmd), cmd, ret); +#endif + + return ret; +} + + +static void* JAMP_GetGameAPI(void* apiversion, void* import) { + orig_apiversion_GGA = (intptr_t)apiversion; + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_GetGameAPI({}, {}) called\n", orig_apiversion_GGA, import); + + // store how we were loaded + s_is_GetGameAPI = true; + + // original import struct from engine + // the struct given by the engine goes out of scope after this returns so we have to copy the whole thing + game_import_t* gi = (game_import_t*)import; + orig_import = *gi; + + // fill in variables of our hooked import struct to pass to the mod + + // pointer to wrapper vmMain function that calls actual mod func from orig_export + g_gameinfo.pfnvmMain = JAMP_vmMain_GGA; + + // pointer to wrapper syscall function that calls actual engine func from orig_import + g_gameinfo.pfnsyscall = JAMP_syscall_GGA; + + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_GetGameAPI({}, {}) returning {}\n", orig_apiversion_GGA, import, (void*)&qmm_export); + + // struct full of export lambdas to QMM's vmMain + // this gets returned to the game engine, but we haven't loaded the mod yet. + // the only thing in this struct the engine uses before calling Init is the apiversion + return &qmm_export; + +} + + static bool JAMP_mod_load(void* entry) { - orig_vmMain = (mod_vmMain)entry; + if (s_is_GetGameAPI) { + mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; + // api version gets passed before import pointer + orig_export = (game_export_t*)pfnGGA((void*)orig_apiversion_GGA, &qmm_import); - return !!orig_vmMain; + return !!orig_export; + } + else { + orig_vmMain_legacy = (mod_vmMain)entry; + return !!orig_vmMain_legacy; + } } static void JAMP_mod_unload() { - orig_vmMain = nullptr; + orig_export = nullptr; + orig_vmMain_legacy = nullptr; } From 3bad92ef60b7251e0a7e619f2420910b742c7fa7 Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 17:16:49 +0200 Subject: [PATCH 05/12] fix comments regarding syscall/vmmain functions in dllEntry games --- src/game_cod11mp.cpp | 4 ++-- src/game_codmp.cpp | 4 ++-- src/game_coduomp.cpp | 4 ++-- src/game_jamp.cpp | 4 ++-- src/game_jk2mp.cpp | 4 ++-- src/game_q3a.cpp | 4 ++-- src/game_rtcwmp.cpp | 4 ++-- src/game_rtcwsp.cpp | 4 ++-- src/game_sof2mp.cpp | 4 ++-- src/game_stvoyhm.cpp | 4 ++-- src/game_wet.cpp | 4 ++-- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/game_cod11mp.cpp b/src/game_cod11mp.cpp index 8451cda..c6b0f38 100644 --- a/src/game_cod11mp.cpp +++ b/src/game_cod11mp.cpp @@ -45,7 +45,7 @@ static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod static mod_vmMain orig_vmMain = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall // this is how QMM and plugins will call into the engine static intptr_t COD11MP_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -92,7 +92,7 @@ static intptr_t COD11MP_syscall(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain // this is how QMM and plugins will call into the mod static intptr_t COD11MP_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); diff --git a/src/game_codmp.cpp b/src/game_codmp.cpp index 17cb6d2..cfa5e7f 100644 --- a/src/game_codmp.cpp +++ b/src/game_codmp.cpp @@ -50,7 +50,7 @@ static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod static mod_vmMain orig_vmMain = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall // this is how QMM and plugins will call into the engine static intptr_t CODMP_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -97,7 +97,7 @@ static intptr_t CODMP_syscall(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain // this is how QMM and plugins will call into the mod static intptr_t CODMP_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); diff --git a/src/game_coduomp.cpp b/src/game_coduomp.cpp index 07164b4..07fdda2 100644 --- a/src/game_coduomp.cpp +++ b/src/game_coduomp.cpp @@ -50,7 +50,7 @@ static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod static mod_vmMain orig_vmMain = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall // this is how QMM and plugins will call into the engine static intptr_t CODUOMP_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -97,7 +97,7 @@ static intptr_t CODUOMP_syscall(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain // this is how QMM and plugins will call into the mod static intptr_t CODUOMP_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); diff --git a/src/game_jamp.cpp b/src/game_jamp.cpp index b8b5d59..28d4be0 100644 --- a/src/game_jamp.cpp +++ b/src/game_jamp.cpp @@ -75,7 +75,7 @@ static eng_syscall orig_syscall_legacy = nullptr; static mod_vmMain orig_vmMain_legacy = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall_legacy // this is how QMM and plugins will call into the engine static intptr_t JAMP_syscall_legacy(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -125,7 +125,7 @@ static intptr_t JAMP_syscall_legacy(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain_legacy // this is how QMM and plugins will call into the mod static intptr_t JAMP_vmMain_legacy(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); diff --git a/src/game_jk2mp.cpp b/src/game_jk2mp.cpp index dda158c..2b092f4 100644 --- a/src/game_jk2mp.cpp +++ b/src/game_jk2mp.cpp @@ -47,7 +47,7 @@ static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod static mod_vmMain orig_vmMain = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall // this is how QMM and plugins will call into the engine static intptr_t JK2MP_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -94,7 +94,7 @@ static intptr_t JK2MP_syscall(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain // this is how QMM and plugins will call into the mod static intptr_t JK2MP_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); diff --git a/src/game_q3a.cpp b/src/game_q3a.cpp index 97f6c0e..3125b84 100644 --- a/src/game_q3a.cpp +++ b/src/game_q3a.cpp @@ -47,7 +47,7 @@ static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod static mod_vmMain orig_vmMain = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall // this is how QMM and plugins will call into the engine static intptr_t Q3A_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -93,7 +93,7 @@ static intptr_t Q3A_syscall(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain // this is how QMM and plugins will call into the mod static intptr_t Q3A_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); diff --git a/src/game_rtcwmp.cpp b/src/game_rtcwmp.cpp index 5f75a01..f7dc57b 100644 --- a/src/game_rtcwmp.cpp +++ b/src/game_rtcwmp.cpp @@ -46,7 +46,7 @@ static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod static mod_vmMain orig_vmMain = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall // this is how QMM and plugins will call into the engine static intptr_t RTCWMP_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -93,7 +93,7 @@ static intptr_t RTCWMP_syscall(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain // this is how QMM and plugins will call into the mod static intptr_t RTCWMP_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); diff --git a/src/game_rtcwsp.cpp b/src/game_rtcwsp.cpp index 81d63de..fab8999 100644 --- a/src/game_rtcwsp.cpp +++ b/src/game_rtcwsp.cpp @@ -46,7 +46,7 @@ static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod static mod_vmMain orig_vmMain = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall // this is how QMM and plugins will call into the engine static intptr_t RTCWSP_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -93,7 +93,7 @@ static intptr_t RTCWSP_syscall(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain // this is how QMM and plugins will call into the mod static intptr_t RTCWSP_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); diff --git a/src/game_sof2mp.cpp b/src/game_sof2mp.cpp index ec2638a..7d58dbd 100644 --- a/src/game_sof2mp.cpp +++ b/src/game_sof2mp.cpp @@ -48,7 +48,7 @@ static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod static mod_vmMain orig_vmMain = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall // this is how QMM and plugins will call into the engine static intptr_t SOF2MP_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -96,7 +96,7 @@ static intptr_t SOF2MP_syscall(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain // this is how QMM and plugins will call into the mod static intptr_t SOF2MP_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); diff --git a/src/game_stvoyhm.cpp b/src/game_stvoyhm.cpp index 9fb6849..9865f7d 100644 --- a/src/game_stvoyhm.cpp +++ b/src/game_stvoyhm.cpp @@ -47,7 +47,7 @@ static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod static mod_vmMain orig_vmMain = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall // this is how QMM and plugins will call into the engine static intptr_t STVOYHM_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -94,7 +94,7 @@ static intptr_t STVOYHM_syscall(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain // this is how QMM and plugins will call into the mod static intptr_t STVOYHM_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); diff --git a/src/game_wet.cpp b/src/game_wet.cpp index 0582f5c..512302f 100644 --- a/src/game_wet.cpp +++ b/src/game_wet.cpp @@ -46,7 +46,7 @@ static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod static mod_vmMain orig_vmMain = nullptr; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func in orig_syscall // this is how QMM and plugins will call into the engine intptr_t WET_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); @@ -93,7 +93,7 @@ intptr_t WET_syscall(intptr_t cmd, ...) { } -// wrapper vmMain function that calls actual mod func from orig_export +// wrapper vmMain function that calls actual mod func in orig_vmMain // this is how QMM and plugins will call into the mod intptr_t WET_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); From c642ddc83d619851b872db7759dcf94baacde275 Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 18:15:03 +0200 Subject: [PATCH 06/12] add all the remaining GEN_IMPORT, GEN_EXPORT, ROUTE_IMPORT, and ROUTE_EXPORT entries for all the import/export functions --- include/game_jamp.h | 5 + src/game_jamp.cpp | 705 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 705 insertions(+), 5 deletions(-) diff --git a/include/game_jamp.h b/include/game_jamp.h index bd97b8f..bd36140 100644 --- a/include/game_jamp.h +++ b/include/game_jamp.h @@ -12,6 +12,11 @@ Created By: #ifndef QMM2_GAME_JAMP_H #define QMM2_GAME_JAMP_H +// these import messages do not exist in the "legacy" JAMP API but they do in GetModuleAPI +enum { + G_SV_REGISTER_SHARED_MEMORY = 90, // void (char *memory) +}; + // these import messages do not have an exact analogue in JAMP enum { G_ARGS = -100, // char* (void) diff --git a/src/game_jamp.cpp b/src/game_jamp.cpp index 28d4be0..80f1820 100644 --- a/src/game_jamp.cpp +++ b/src/game_jamp.cpp @@ -188,13 +188,358 @@ static game_export_t* orig_export = nullptr; // struct with lambdas that call QMM's syscall function. this is given to the mod static game_import_t qmm_import = { GEN_IMPORT(Print, G_PRINT), - // todo finish + GEN_IMPORT(Error, G_ERROR), + GEN_IMPORT(Milliseconds, G_MILLISECONDS), + GEN_IMPORT(PrecisionTimerStart, G_PRECISIONTIMER_START), + GEN_IMPORT(PrecisionTimerEnd, G_PRECISIONTIMER_END), + GEN_IMPORT(SV_RegisterSharedMemory, G_SV_REGISTER_SHARED_MEMORY), + GEN_IMPORT(RealTime, G_REAL_TIME), + GEN_IMPORT(TrueMalloc, G_TRUEMALLOC), + GEN_IMPORT(TrueFree, G_TRUEFREE), + GEN_IMPORT(SnapVector, G_SNAPVECTOR), + GEN_IMPORT(Cvar_Register, G_CVAR_REGISTER), + GEN_IMPORT(Cvar_Set, G_CVAR_SET), + GEN_IMPORT(Cvar_Update, G_CVAR_UPDATE), + GEN_IMPORT(Cvar_VariableIntegerValue, G_CVAR_VARIABLE_INTEGER_VALUE), + GEN_IMPORT(Cvar_VariableStringBuffer, G_CVAR_VARIABLE_STRING_BUFFER), + GEN_IMPORT(Argc, G_ARGC), + GEN_IMPORT(Argv, G_ARGV), + GEN_IMPORT(FS_Close, G_FS_FCLOSE_FILE), + GEN_IMPORT(FS_GetFileList, G_FS_GETFILELIST), + GEN_IMPORT(FS_Open, G_FS_FOPEN_FILE), + GEN_IMPORT(FS_Read, G_FS_READ), + GEN_IMPORT(FS_Write, G_FS_WRITE), + GEN_IMPORT(AdjustAreaPortalState, G_ADJUST_AREA_PORTAL_STATE), + GEN_IMPORT(AreasConnected, G_AREAS_CONNECTED), + GEN_IMPORT(DebugPolygonCreate, G_DEBUG_POLYGON_CREATE), + GEN_IMPORT(DebugPolygonDelete, G_DEBUG_POLYGON_DELETE), + GEN_IMPORT(DropClient, G_DROP_CLIENT), + GEN_IMPORT(EntitiesInBox, G_ENTITIES_IN_BOX), + GEN_IMPORT(EntityContact, G_ENTITY_CONTACT), + GEN_IMPORT(GetConfigstring, G_GET_CONFIGSTRING), + GEN_IMPORT(GetEntityToken, G_GET_ENTITY_TOKEN), + GEN_IMPORT(GetServerinfo, G_GET_SERVERINFO), + GEN_IMPORT(GetUsercmd, G_GET_USERCMD), + GEN_IMPORT(GetUserinfo, G_GET_USERINFO), + GEN_IMPORT(InPVS, G_IN_PVS), + GEN_IMPORT(InPVSIgnorePortals, G_IN_PVS_IGNORE_PORTALS), + GEN_IMPORT(LinkEntity, G_LINKENTITY), + GEN_IMPORT(LocateGameData, G_LOCATE_GAME_DATA), + GEN_IMPORT(PointContents, G_POINT_CONTENTS), + GEN_IMPORT(SendConsoleCommand, G_SEND_CONSOLE_COMMAND), + GEN_IMPORT(SendServerCommand, G_SEND_SERVER_COMMAND), + GEN_IMPORT(SetBrushModel, G_SET_BRUSH_MODEL), + GEN_IMPORT(SetConfigstring, G_SET_CONFIGSTRING), + GEN_IMPORT(SetServerCull, G_SET_SERVER_CULL), + GEN_IMPORT(SetUserinfo, G_SET_USERINFO), + GEN_IMPORT(SiegePersSet, G_SIEGEPERSSET), + GEN_IMPORT(SiegePersGet, G_SIEGEPERSGET), + GEN_IMPORT(Trace, G_TRACE), + GEN_IMPORT(UnlinkEntity, G_UNLINKENTITY), + GEN_IMPORT(ROFF_Clean, G_ROFF_CLEAN), + GEN_IMPORT(ROFF_UpdateEntities, G_ROFF_UPDATE_ENTITIES), + GEN_IMPORT(ROFF_Cache, G_ROFF_CACHE), + GEN_IMPORT(ROFF_Play, G_ROFF_PLAY), + GEN_IMPORT(ROFF_Purge_Ent, G_ROFF_PURGE_ENT), + GEN_IMPORT(ICARUS_RunScript, G_ICARUS_RUNSCRIPT), + GEN_IMPORT(ICARUS_RegisterScript, G_ICARUS_REGISTERSCRIPT), + GEN_IMPORT(ICARUS_Init, G_ICARUS_INIT), + GEN_IMPORT(ICARUS_ValidEnt, G_ICARUS_VALIDENT), + GEN_IMPORT(ICARUS_IsInitialized, G_ICARUS_ISINITIALIZED), + GEN_IMPORT(ICARUS_MaintainTaskManager, G_ICARUS_MAINTAINTASKMANAGER), + GEN_IMPORT(ICARUS_IsRunning, G_ICARUS_ISRUNNING), + GEN_IMPORT(ICARUS_TaskIDPending, G_ICARUS_TASKIDPENDING), + GEN_IMPORT(ICARUS_InitEnt, G_ICARUS_INITENT), + GEN_IMPORT(ICARUS_FreeEnt, G_ICARUS_FREEENT), + GEN_IMPORT(ICARUS_AssociateEnt, G_ICARUS_ASSOCIATEENT), + GEN_IMPORT(ICARUS_Shutdown, G_ICARUS_SHUTDOWN), + GEN_IMPORT(ICARUS_TaskIDSet, G_ICARUS_TASKIDSET), + GEN_IMPORT(ICARUS_TaskIDComplete, G_ICARUS_TASKIDCOMPLETE), + GEN_IMPORT(ICARUS_SetVar, G_ICARUS_SETVAR), + GEN_IMPORT(ICARUS_VariableDeclared, G_ICARUS_VARIABLEDECLARED), + GEN_IMPORT(ICARUS_GetFloatVariable, G_ICARUS_GETFLOATVARIABLE), + GEN_IMPORT(ICARUS_GetStringVariable, G_ICARUS_GETSTRINGVARIABLE), + GEN_IMPORT(ICARUS_GetVectorVariable, G_ICARUS_GETVECTORVARIABLE), + GEN_IMPORT(Nav_Init, G_NAV_INIT), + GEN_IMPORT(Nav_Free, G_NAV_FREE), + GEN_IMPORT(Nav_Load, G_NAV_LOAD), + GEN_IMPORT(Nav_Save, G_NAV_SAVE), + GEN_IMPORT(Nav_AddRawPoint, G_NAV_ADDRAWPOINT), + GEN_IMPORT(Nav_CalculatePaths, G_NAV_CALCULATEPATHS), + GEN_IMPORT(Nav_HardConnect, G_NAV_HARDCONNECT), + GEN_IMPORT(Nav_ShowNodes, G_NAV_SHOWNODES), + GEN_IMPORT(Nav_ShowEdges, G_NAV_SHOWEDGES), + GEN_IMPORT(Nav_ShowPath, G_NAV_SHOWPATH), + GEN_IMPORT(Nav_GetNearestNode, G_NAV_GETNEARESTNODE), + GEN_IMPORT(Nav_GetBestNode, G_NAV_GETBESTNODE), + GEN_IMPORT(Nav_GetNodePosition, G_NAV_GETNODEPOSITION), + GEN_IMPORT(Nav_GetNodeNumEdges, G_NAV_GETNODENUMEDGES), + GEN_IMPORT(Nav_GetNodeEdge, G_NAV_GETNODEEDGE), + GEN_IMPORT(Nav_GetNumNodes, G_NAV_GETNUMNODES), + GEN_IMPORT(Nav_Connected, G_NAV_CONNECTED), + GEN_IMPORT(Nav_GetPathCost, G_NAV_GETPATHCOST), + GEN_IMPORT(Nav_GetEdgeCost, G_NAV_GETEDGECOST), + GEN_IMPORT(Nav_GetProjectedNode, G_NAV_GETPROJECTEDNODE), + GEN_IMPORT(Nav_CheckFailedNodes, G_NAV_CHECKFAILEDNODES), + GEN_IMPORT(Nav_AddFailedNode, G_NAV_ADDFAILEDNODE), + GEN_IMPORT(Nav_NodeFailed, G_NAV_NODEFAILED), + GEN_IMPORT(Nav_NodesAreNeighbors, G_NAV_NODESARENEIGHBORS), + GEN_IMPORT(Nav_ClearFailedEdge, G_NAV_CLEARFAILEDEDGE), + GEN_IMPORT(Nav_ClearAllFailedEdges, G_NAV_CLEARALLFAILEDEDGES), + GEN_IMPORT(Nav_EdgeFailed, G_NAV_EDGEFAILED), + GEN_IMPORT(Nav_AddFailedEdge, G_NAV_ADDFAILEDEDGE), + GEN_IMPORT(Nav_CheckFailedEdge, G_NAV_CHECKFAILEDEDGE), + GEN_IMPORT(Nav_CheckAllFailedEdges, G_NAV_CHECKALLFAILEDEDGES), + GEN_IMPORT(Nav_RouteBlocked, G_NAV_ROUTEBLOCKED), + GEN_IMPORT(Nav_GetBestNodeAltRoute, G_NAV_GETBESTNODEALTROUTE), + GEN_IMPORT(Nav_GetBestNodeAltRoute2, G_NAV_GETBESTNODEALT2), + GEN_IMPORT(Nav_GetBestPathBetweenEnts, G_NAV_GETBESTPATHBETWEENENTS), + GEN_IMPORT(Nav_GetNodeRadius, G_NAV_GETNODERADIUS), + GEN_IMPORT(Nav_CheckBlockedEdges, G_NAV_CHECKBLOCKEDEDGES), + GEN_IMPORT(Nav_ClearCheckedNodes, G_NAV_CLEARCHECKEDNODES), + GEN_IMPORT(Nav_CheckedNode, G_NAV_CHECKEDNODE), + GEN_IMPORT(Nav_SetCheckedNode, G_NAV_SETCHECKEDNODE), + GEN_IMPORT(Nav_FlagAllNodes, G_NAV_FLAGALLNODES), + GEN_IMPORT(Nav_GetPathsCalculated, G_NAV_GETPATHSCALCULATED), + GEN_IMPORT(Nav_SetPathsCalculated, G_NAV_SETPATHSCALCULATED), + GEN_IMPORT(BotAllocateClient, G_BOT_ALLOCATE_CLIENT), + GEN_IMPORT(BotFreeClient, G_BOT_FREE_CLIENT), + GEN_IMPORT(BotLoadCharacter, BOTLIB_AI_LOAD_CHARACTER), + GEN_IMPORT(BotFreeCharacter, BOTLIB_AI_FREE_CHARACTER), + GEN_IMPORT(Characteristic_Float, BOTLIB_AI_CHARACTERISTIC_FLOAT), + GEN_IMPORT(Characteristic_BFloat, BOTLIB_AI_CHARACTERISTIC_BFLOAT), + GEN_IMPORT(Characteristic_Integer, BOTLIB_AI_CHARACTERISTIC_INTEGER), + GEN_IMPORT(Characteristic_BInteger, BOTLIB_AI_CHARACTERISTIC_BINTEGER), + GEN_IMPORT(Characteristic_String, BOTLIB_AI_CHARACTERISTIC_STRING), + GEN_IMPORT(BotAllocChatState, BOTLIB_AI_ALLOC_CHAT_STATE), + GEN_IMPORT(BotFreeChatState, BOTLIB_AI_FREE_CHAT_STATE), + GEN_IMPORT(BotQueueConsoleMessage, BOTLIB_AI_QUEUE_CONSOLE_MESSAGE), + GEN_IMPORT(BotRemoveConsoleMessage, BOTLIB_AI_REMOVE_CONSOLE_MESSAGE), + GEN_IMPORT(BotNextConsoleMessage, BOTLIB_AI_NEXT_CONSOLE_MESSAGE), + GEN_IMPORT(BotNumConsoleMessages, BOTLIB_AI_NUM_CONSOLE_MESSAGE), + GEN_IMPORT(BotInitialChat, BOTLIB_AI_INITIAL_CHAT), + GEN_IMPORT(BotReplyChat, BOTLIB_AI_REPLY_CHAT), + GEN_IMPORT(BotChatLength, BOTLIB_AI_CHAT_LENGTH), + GEN_IMPORT(BotEnterChat, BOTLIB_AI_ENTER_CHAT), + GEN_IMPORT(StringContains, BOTLIB_AI_STRING_CONTAINS), + GEN_IMPORT(BotFindMatch, BOTLIB_AI_FIND_MATCH), + GEN_IMPORT(BotMatchVariable, BOTLIB_AI_MATCH_VARIABLE), + GEN_IMPORT(UnifyWhiteSpaces, BOTLIB_AI_UNIFY_WHITE_SPACES), + GEN_IMPORT(BotReplaceSynonyms, BOTLIB_AI_REPLACE_SYNONYMS), + GEN_IMPORT(BotLoadChatFile, BOTLIB_AI_LOAD_CHAT_FILE), + GEN_IMPORT(BotSetChatGender, BOTLIB_AI_SET_CHAT_GENDER), + GEN_IMPORT(BotSetChatName, BOTLIB_AI_SET_CHAT_NAME), + GEN_IMPORT(BotResetGoalState, BOTLIB_AI_RESET_GOAL_STATE), + GEN_IMPORT(BotResetAvoidGoals, BOTLIB_AI_RESET_AVOID_GOALS), + GEN_IMPORT(BotPushGoal, BOTLIB_AI_PUSH_GOAL), + GEN_IMPORT(BotPopGoal, BOTLIB_AI_POP_GOAL), + GEN_IMPORT(BotEmptyGoalStack, BOTLIB_AI_EMPTY_GOAL_STACK), + GEN_IMPORT(BotDumpAvoidGoals, BOTLIB_AI_DUMP_AVOID_GOALS), + GEN_IMPORT(BotDumpGoalStack, BOTLIB_AI_DUMP_GOAL_STACK), + GEN_IMPORT(BotGoalName, BOTLIB_AI_GOAL_NAME), + GEN_IMPORT(BotGetTopGoal, BOTLIB_AI_GET_TOP_GOAL), + GEN_IMPORT(BotGetSecondGoal, BOTLIB_AI_GET_SECOND_GOAL), + GEN_IMPORT(BotChooseLTGItem, BOTLIB_AI_CHOOSE_LTG_ITEM), + GEN_IMPORT(BotChooseNBGItem, BOTLIB_AI_CHOOSE_NBG_ITEM), + GEN_IMPORT(BotTouchingGoal, BOTLIB_AI_TOUCHING_GOAL), + GEN_IMPORT(BotItemGoalInVisButNotVisible, BOTLIB_AI_ITEM_GOAL_IN_VIS_BUT_NOT_VISIBLE), + GEN_IMPORT(BotGetLevelItemGoal, BOTLIB_AI_GET_LEVEL_ITEM_GOAL), + GEN_IMPORT(BotAvoidGoalTime, BOTLIB_AI_AVOID_GOAL_TIME), + GEN_IMPORT(BotInitLevelItems, BOTLIB_AI_INIT_LEVEL_ITEMS), + GEN_IMPORT(BotUpdateEntityItems, BOTLIB_AI_UPDATE_ENTITY_ITEMS), + GEN_IMPORT(BotLoadItemWeights, BOTLIB_AI_LOAD_ITEM_WEIGHTS), + GEN_IMPORT(BotFreeItemWeights, BOTLIB_AI_FREE_ITEM_WEIGHTS), + GEN_IMPORT(BotSaveGoalFuzzyLogic, BOTLIB_AI_SAVE_GOAL_FUZZY_LOGIC), + GEN_IMPORT(BotAllocGoalState, BOTLIB_AI_ALLOC_GOAL_STATE), + GEN_IMPORT(BotFreeGoalState, BOTLIB_AI_FREE_GOAL_STATE), + GEN_IMPORT(BotResetMoveState, BOTLIB_AI_RESET_MOVE_STATE), + GEN_IMPORT(BotMoveToGoal, BOTLIB_AI_MOVE_TO_GOAL), + GEN_IMPORT(BotMoveInDirection, BOTLIB_AI_MOVE_IN_DIRECTION), + GEN_IMPORT(BotResetAvoidReach, BOTLIB_AI_RESET_AVOID_REACH), + GEN_IMPORT(BotResetLastAvoidReach, BOTLIB_AI_RESET_LAST_AVOID_REACH), + GEN_IMPORT(BotReachabilityArea, BOTLIB_AI_REACHABILITY_AREA), + GEN_IMPORT(BotMovementViewTarget, BOTLIB_AI_MOVEMENT_VIEW_TARGET), + GEN_IMPORT(BotAllocMoveState, BOTLIB_AI_ALLOC_MOVE_STATE), + GEN_IMPORT(BotFreeMoveState, BOTLIB_AI_FREE_MOVE_STATE), + GEN_IMPORT(BotInitMoveState, BOTLIB_AI_INIT_MOVE_STATE), + GEN_IMPORT(BotChooseBestFightWeapon, BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON), + GEN_IMPORT(BotGetWeaponInfo, BOTLIB_AI_GET_WEAPON_INFO), + GEN_IMPORT(BotLoadWeaponWeights, BOTLIB_AI_LOAD_WEAPON_WEIGHTS), + GEN_IMPORT(BotAllocWeaponState, BOTLIB_AI_ALLOC_WEAPON_STATE), + GEN_IMPORT(BotFreeWeaponState, BOTLIB_AI_FREE_WEAPON_STATE), + GEN_IMPORT(BotResetWeaponState, BOTLIB_AI_RESET_WEAPON_STATE), + GEN_IMPORT(GeneticParentsAndChildSelection, BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION), + GEN_IMPORT(BotInterbreedGoalFuzzyLogic, BOTLIB_AI_INTERBREED_GOAL_FUZZY_LOGIC), + GEN_IMPORT(BotMutateGoalFuzzyLogic, BOTLIB_AI_MUTATE_GOAL_FUZZY_LOGIC), + GEN_IMPORT(BotGetNextCampSpotGoal, BOTLIB_AI_GET_NEXT_CAMP_SPOT_GOAL), + GEN_IMPORT(BotGetMapLocationGoal, BOTLIB_AI_GET_MAP_LOCATION_GOAL), + GEN_IMPORT(BotNumInitialChats, BOTLIB_AI_NUM_INITIAL_CHATS), + GEN_IMPORT(BotGetChatMessage, BOTLIB_AI_GET_CHAT_MESSAGE), + GEN_IMPORT(BotRemoveFromAvoidGoals, BOTLIB_AI_REMOVE_FROM_AVOID_GOALS), + GEN_IMPORT(BotPredictVisiblePosition, BOTLIB_AI_PREDICT_VISIBLE_POSITION), + GEN_IMPORT(BotSetAvoidGoalTime, BOTLIB_AI_SET_AVOID_GOAL_TIME), + GEN_IMPORT(BotAddAvoidSpot, BOTLIB_AI_ADD_AVOID_SPOT), + GEN_IMPORT(BotLibSetup, BOTLIB_SETUP), + GEN_IMPORT(BotLibShutdown, BOTLIB_SHUTDOWN), + GEN_IMPORT(BotLibVarSet, BOTLIB_LIBVAR_SET), + GEN_IMPORT(BotLibVarGet, BOTLIB_LIBVAR_GET), + GEN_IMPORT(BotLibDefine, BOTLIB_PC_ADD_GLOBAL_DEFINE), + GEN_IMPORT(BotLibStartFrame, BOTLIB_START_FRAME), + GEN_IMPORT(BotLibLoadMap, BOTLIB_LOAD_MAP), + GEN_IMPORT(BotLibUpdateEntity, BOTLIB_UPDATENTITY), + GEN_IMPORT(BotLibTest, BOTLIB_TEST), + GEN_IMPORT(BotGetSnapshotEntity, BOTLIB_GET_SNAPSHOT_ENTITY), + GEN_IMPORT(BotGetServerCommand, BOTLIB_GET_CONSOLE_MESSAGE), + GEN_IMPORT(BotUserCommand, BOTLIB_USER_COMMAND), + GEN_IMPORT(BotUpdateWaypoints, G_BOT_UPDATEWAYPOINTS), + GEN_IMPORT(BotCalculatePaths, G_BOT_CALCULATEPATHS), + GEN_IMPORT(AAS_EnableRoutingArea, BOTLIB_AAS_ENABLE_ROUTING_AREA), + GEN_IMPORT(AAS_BBoxAreas, BOTLIB_AAS_BBOX_AREAS), + GEN_IMPORT(AAS_AreaInfo, BOTLIB_AAS_AREA_INFO), + GEN_IMPORT(AAS_EntityInfo, BOTLIB_AAS_ENTITY_INFO), + GEN_IMPORT(AAS_Initialized, BOTLIB_AAS_INITIALIZED), + GEN_IMPORT(AAS_PresenceTypeBoundingBox, BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX), + GEN_IMPORT(AAS_Time, BOTLIB_AAS_TIME), + GEN_IMPORT(AAS_PointAreaNum, BOTLIB_AAS_POINT_AREA_NUM), + GEN_IMPORT(AAS_TraceAreas, BOTLIB_AAS_TRACE_AREAS), + GEN_IMPORT(AAS_PointContents, BOTLIB_AAS_POINT_CONTENTS), + GEN_IMPORT(AAS_NextBSPEntity, BOTLIB_AAS_NEXT_BSP_ENTITY), + GEN_IMPORT(AAS_ValueForBSPEpairKey, BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY), + GEN_IMPORT(AAS_VectorForBSPEpairKey, BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY), + GEN_IMPORT(AAS_FloatForBSPEpairKey, BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY), + GEN_IMPORT(AAS_IntForBSPEpairKey, BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY), + GEN_IMPORT(AAS_AreaReachability, BOTLIB_AAS_AREA_REACHABILITY), + GEN_IMPORT(AAS_AreaTravelTimeToGoalArea, BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA), + GEN_IMPORT(AAS_Swimming, BOTLIB_AAS_SWIMMING), + GEN_IMPORT(AAS_PredictClientMovement, BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT), + GEN_IMPORT(AAS_AlternativeRouteGoals, BOTLIB_AAS_ALTERNATIVE_ROUTE_GOAL), + GEN_IMPORT(AAS_PredictRoute, BOTLIB_AAS_PREDICT_ROUTE), + GEN_IMPORT(AAS_PointReachabilityAreaIndex, BOTLIB_AAS_POINT_REACHABILITY_AREA_INDEX), + GEN_IMPORT(EA_Say, BOTLIB_EA_SAY), + GEN_IMPORT(EA_SayTeam, BOTLIB_EA_SAY_TEAM), + GEN_IMPORT(EA_Command, BOTLIB_EA_COMMAND), + GEN_IMPORT(EA_Action, BOTLIB_EA_ACTION), + GEN_IMPORT(EA_Gesture, BOTLIB_EA_GESTURE), + GEN_IMPORT(EA_Talk, BOTLIB_EA_TALK), + GEN_IMPORT(EA_Attack, BOTLIB_EA_ATTACK), + GEN_IMPORT(EA_Alt_Attack, BOTLIB_EA_ALT_ATTACK), + GEN_IMPORT(EA_ForcePower, BOTLIB_EA_FORCEPOWER), + GEN_IMPORT(EA_Use, BOTLIB_EA_USE), + GEN_IMPORT(EA_Respawn, BOTLIB_EA_RESPAWN), + GEN_IMPORT(EA_Crouch, BOTLIB_EA_CROUCH), + GEN_IMPORT(EA_MoveUp, BOTLIB_EA_MOVE_UP), + GEN_IMPORT(EA_MoveDown, BOTLIB_EA_MOVE_DOWN), + GEN_IMPORT(EA_MoveForward, BOTLIB_EA_MOVE_FORWARD), + GEN_IMPORT(EA_MoveBack, BOTLIB_EA_MOVE_BACK), + GEN_IMPORT(EA_MoveLeft, BOTLIB_EA_MOVE_LEFT), + GEN_IMPORT(EA_MoveRight, BOTLIB_EA_MOVE_RIGHT), + GEN_IMPORT(EA_SelectWeapon, BOTLIB_EA_SELECT_WEAPON), + GEN_IMPORT(EA_Jump, BOTLIB_EA_JUMP), + GEN_IMPORT(EA_DelayedJump, BOTLIB_EA_DELAYED_JUMP), + GEN_IMPORT(EA_Move, BOTLIB_EA_MOVE), + GEN_IMPORT(EA_View, BOTLIB_EA_VIEW), + GEN_IMPORT(EA_EndRegular, BOTLIB_EA_END_REGULAR), + GEN_IMPORT(EA_GetInput, BOTLIB_EA_GET_INPUT), + GEN_IMPORT(EA_ResetInput, BOTLIB_EA_RESET_INPUT), + GEN_IMPORT(PC_LoadSource, BOTLIB_PC_LOAD_SOURCE), + GEN_IMPORT(PC_FreeSource, BOTLIB_PC_FREE_SOURCE), + GEN_IMPORT(PC_ReadToken, BOTLIB_PC_READ_TOKEN), + GEN_IMPORT(PC_SourceFileAndLine, BOTLIB_PC_SOURCE_FILE_AND_LINE), + GEN_IMPORT(R_RegisterSkin, G_R_REGISTERSKIN), + GEN_IMPORT(SetActiveSubBSP, G_SET_ACTIVE_SUBBSP), + GEN_IMPORT(CM_RegisterTerrain, G_CM_REGISTER_TERRAIN), + GEN_IMPORT(RMG_Init, G_RMG_INIT), + GEN_IMPORT(G2API_ListModelBones, G_G2_LISTBONES), + GEN_IMPORT(G2API_ListModelSurfaces, G_G2_LISTSURFACES), + GEN_IMPORT(G2API_HaveWeGhoul2Models, G_G2_HAVEWEGHOULMODELS), + GEN_IMPORT(G2API_SetGhoul2ModelIndexes, G_G2_SETMODELS), + GEN_IMPORT(G2API_GetBoltMatrix, G_G2_GETBOLT), + GEN_IMPORT(G2API_GetBoltMatrix_NoReconstruct, G_G2_GETBOLT_NOREC), + GEN_IMPORT(G2API_GetBoltMatrix_NoRecNoRot, G_G2_GETBOLT_NOREC_NOROT), + GEN_IMPORT(G2API_InitGhoul2Model, G_G2_INITGHOUL2MODEL), + GEN_IMPORT(G2API_SetSkin, G_G2_SETSKIN), + GEN_IMPORT(G2API_Ghoul2Size, G_G2_SIZE), + GEN_IMPORT(G2API_AddBolt, G_G2_ADDBOLT), + GEN_IMPORT(G2API_SetBoltInfo, G_G2_SETBOLTINFO), + GEN_IMPORT(G2API_SetBoneAngles, G_G2_ANGLEOVERRIDE), + GEN_IMPORT(G2API_SetBoneAnim, G_G2_PLAYANIM), + GEN_IMPORT(G2API_GetBoneAnim, G_G2_GETBONEANIM), + GEN_IMPORT(G2API_GetGLAName, G_G2_GETGLANAME), + GEN_IMPORT(G2API_CopyGhoul2Instance, G_G2_COPYGHOUL2INSTANCE), + GEN_IMPORT(G2API_CopySpecificGhoul2Model, G_G2_COPYSPECIFICGHOUL2MODEL), + GEN_IMPORT(G2API_DuplicateGhoul2Instance, G_G2_DUPLICATEGHOUL2INSTANCE), + GEN_IMPORT(G2API_HasGhoul2ModelOnIndex, G_G2_HASGHOUL2MODELONINDEX), + GEN_IMPORT(G2API_RemoveGhoul2Model, G_G2_REMOVEGHOUL2MODEL), + GEN_IMPORT(G2API_RemoveGhoul2Models, G_G2_REMOVEGHOUL2MODELS), + GEN_IMPORT(G2API_CleanGhoul2Models, G_G2_CLEANMODELS), + GEN_IMPORT(G2API_CollisionDetect, G_G2_COLLISIONDETECT), + GEN_IMPORT(G2API_CollisionDetectCache, G_G2_COLLISIONDETECTCACHE), + GEN_IMPORT(G2API_SetRootSurface, G_G2_SETROOTSURFACE), + GEN_IMPORT(G2API_SetSurfaceOnOff, G_G2_SETSURFACEONOFF), + GEN_IMPORT(G2API_SetNewOrigin, G_G2_SETNEWORIGIN), + GEN_IMPORT(G2API_DoesBoneExist, G_G2_DOESBONEEXIST), + GEN_IMPORT(G2API_GetSurfaceRenderStatus, G_G2_GETSURFACERENDERSTATUS), + GEN_IMPORT(G2API_AbsurdSmoothing, G_G2_ABSURDSMOOTHING), + GEN_IMPORT(G2API_SetRagDoll, G_G2_SETRAGDOLL), + GEN_IMPORT(G2API_AnimateG2Models, G_G2_ANIMATEG2MODELS), + GEN_IMPORT(G2API_RagPCJConstraint, G_G2_RAGPCJCONSTRAINT), + GEN_IMPORT(G2API_RagPCJGradientSpeed, G_G2_RAGPCJGRADIENTSPEED), + GEN_IMPORT(G2API_RagEffectorGoal, G_G2_RAGEFFECTORGOAL), + GEN_IMPORT(G2API_GetRagBonePos, G_G2_GETRAGBONEPOS), + GEN_IMPORT(G2API_RagEffectorKick, G_G2_RAGEFFECTORKICK), + GEN_IMPORT(G2API_RagForceSolve, G_G2_RAGFORCESOLVE), + GEN_IMPORT(G2API_SetBoneIKState, G_G2_SETBONEIKSTATE), + GEN_IMPORT(G2API_IKMove, G_G2_IKMOVE), + GEN_IMPORT(G2API_RemoveBone, G_G2_REMOVEBONE), + GEN_IMPORT(G2API_AttachInstanceToEntNum, G_G2_ATTACHINSTANCETOENTNUM), + GEN_IMPORT(G2API_ClearAttachedInstance, G_G2_CLEARATTACHEDINSTANCE), + GEN_IMPORT(G2API_CleanEntAttachments, G_G2_CLEANENTATTACHMENTS), + GEN_IMPORT(G2API_OverrideServer, G_G2_OVERRIDESERVER), + GEN_IMPORT(G2API_GetSurfaceName, G_G2_GETSURFACENAME), }; // struct with lambdas that call QMM's vmMain function. this is given to the game engine static game_export_t qmm_export = { GEN_EXPORT(InitGame, GAME_INIT), - // todo finish + GEN_EXPORT(ShutdownGame, GAME_SHUTDOWN), + GEN_EXPORT(ClientConnect, GAME_CLIENT_CONNECT), + GEN_EXPORT(ClientBegin, GAME_CLIENT_BEGIN), + GEN_EXPORT(ClientUserinfoChanged, GAME_CLIENT_USERINFO_CHANGED), + GEN_EXPORT(ClientDisconnect, GAME_CLIENT_DISCONNECT), + GEN_EXPORT(ClientCommand, GAME_CLIENT_COMMAND), + GEN_EXPORT(ClientThink, GAME_CLIENT_THINK), + GEN_EXPORT(RunFrame, GAME_RUN_FRAME), + GEN_EXPORT(ConsoleCommand, GAME_CONSOLE_COMMAND), + GEN_EXPORT(BotAIStartFrame, BOTAI_START_FRAME), + GEN_EXPORT(ROFF_NotetrackCallback, GAME_ROFF_NOTETRACK_CALLBACK), + GEN_EXPORT(SpawnRMGEntity, GAME_SPAWN_RMG_ENTITY), + GEN_EXPORT(ICARUS_PlaySound, GAME_ICARUS_PLAYSOUND), + GEN_EXPORT(ICARUS_Set, GAME_ICARUS_SET), + GEN_EXPORT(ICARUS_Lerp2Pos, GAME_ICARUS_LERP2POS), + GEN_EXPORT(ICARUS_Lerp2Origin, GAME_ICARUS_LERP2ORIGIN), + GEN_EXPORT(ICARUS_Lerp2Angles, GAME_ICARUS_LERP2ANGLES), + GEN_EXPORT(ICARUS_GetTag, GAME_ICARUS_GETTAG), + GEN_EXPORT(ICARUS_Lerp2Start, GAME_ICARUS_LERP2START), + GEN_EXPORT(ICARUS_Lerp2End, GAME_ICARUS_LERP2END), + GEN_EXPORT(ICARUS_Use, GAME_ICARUS_USE), + GEN_EXPORT(ICARUS_Kill, GAME_ICARUS_KILL), + GEN_EXPORT(ICARUS_Remove, GAME_ICARUS_REMOVE), + GEN_EXPORT(ICARUS_Play, GAME_ICARUS_PLAY), + GEN_EXPORT(ICARUS_GetFloat, GAME_ICARUS_GETFLOAT), + GEN_EXPORT(ICARUS_GetVector, GAME_ICARUS_GETVECTOR), + GEN_EXPORT(ICARUS_GetString, GAME_ICARUS_GETSTRING), + GEN_EXPORT(ICARUS_SoundIndex, GAME_ICARUS_SOUNDINDEX), + GEN_EXPORT(ICARUS_GetSetIDForString, GAME_ICARUS_GETSETIDFORSTRING), + GEN_EXPORT(NAV_ClearPathToPoint, GAME_NAV_CLEARPATHTOPOINT), + GEN_EXPORT(NPC_ClearLOS2, GAME_NAV_CLEARLOS), + GEN_EXPORT(NAVNEW_ClearPathBetweenPoints, GAME_NAV_CLEARPATHBETWEENPOINTS), + GEN_EXPORT(NAV_CheckNodeFailedForEnt, GAME_NAV_CHECKNODEFAILEDFORENT), + GEN_EXPORT(NAV_EntIsUnlockedDoor, GAME_NAV_ENTISUNLOCKEDDOOR), + GEN_EXPORT(NAV_EntIsDoor, GAME_NAV_ENTISDOOR), + GEN_EXPORT(NAV_EntIsBreakable, GAME_NAV_ENTISBREAKABLE), + GEN_EXPORT(NAV_EntIsRemovableUsable, GAME_NAV_ENTISREMOVABLEUSABLE), + GEN_EXPORT(NAV_FindCombatPointWaypoints, GAME_NAV_FINDCOMBATPOINTWAYPOINTS), + GEN_EXPORT(BG_GetItemIndexByTag, GAME_GETITEMINDEXBYTAG), }; @@ -215,6 +560,314 @@ static intptr_t JAMP_syscall_GGA(intptr_t cmd, ...) { switch (cmd) { ROUTE_IMPORT(Print, G_PRINT); + ROUTE_IMPORT(Error, G_ERROR); + ROUTE_IMPORT(Milliseconds, G_MILLISECONDS); + ROUTE_IMPORT(PrecisionTimerStart, G_PRECISIONTIMER_START); + ROUTE_IMPORT(PrecisionTimerEnd, G_PRECISIONTIMER_END); + ROUTE_IMPORT(SV_RegisterSharedMemory, G_SV_REGISTER_SHARED_MEMORY); + ROUTE_IMPORT(RealTime, G_REAL_TIME); + ROUTE_IMPORT(TrueMalloc, G_TRUEMALLOC); + ROUTE_IMPORT(TrueFree, G_TRUEFREE); + ROUTE_IMPORT(SnapVector, G_SNAPVECTOR); + ROUTE_IMPORT(Cvar_Register, G_CVAR_REGISTER); + ROUTE_IMPORT(Cvar_Set, G_CVAR_SET); + ROUTE_IMPORT(Cvar_Update, G_CVAR_UPDATE); + ROUTE_IMPORT(Cvar_VariableIntegerValue, G_CVAR_VARIABLE_INTEGER_VALUE); + ROUTE_IMPORT(Cvar_VariableStringBuffer, G_CVAR_VARIABLE_STRING_BUFFER); + ROUTE_IMPORT(Argc, G_ARGC); + ROUTE_IMPORT(Argv, G_ARGV); + ROUTE_IMPORT(FS_Close, G_FS_FCLOSE_FILE); + ROUTE_IMPORT(FS_GetFileList, G_FS_GETFILELIST); + ROUTE_IMPORT(FS_Open, G_FS_FOPEN_FILE); + ROUTE_IMPORT(FS_Read, G_FS_READ); + ROUTE_IMPORT(FS_Write, G_FS_WRITE); + ROUTE_IMPORT(AdjustAreaPortalState, G_ADJUST_AREA_PORTAL_STATE); + ROUTE_IMPORT(AreasConnected, G_AREAS_CONNECTED); + ROUTE_IMPORT(DebugPolygonCreate, G_DEBUG_POLYGON_CREATE); + ROUTE_IMPORT(DebugPolygonDelete, G_DEBUG_POLYGON_DELETE); + ROUTE_IMPORT(DropClient, G_DROP_CLIENT); + ROUTE_IMPORT(EntitiesInBox, G_ENTITIES_IN_BOX); + ROUTE_IMPORT(EntityContact, G_ENTITY_CONTACT); + ROUTE_IMPORT(GetConfigstring, G_GET_CONFIGSTRING); + ROUTE_IMPORT(GetEntityToken, G_GET_ENTITY_TOKEN); + ROUTE_IMPORT(GetServerinfo, G_GET_SERVERINFO); + ROUTE_IMPORT(GetUsercmd, G_GET_USERCMD); + ROUTE_IMPORT(GetUserinfo, G_GET_USERINFO); + ROUTE_IMPORT(InPVS, G_IN_PVS); + ROUTE_IMPORT(InPVSIgnorePortals, G_IN_PVS_IGNORE_PORTALS); + ROUTE_IMPORT(LinkEntity, G_LINKENTITY); + ROUTE_IMPORT(LocateGameData, G_LOCATE_GAME_DATA); + ROUTE_IMPORT(PointContents, G_POINT_CONTENTS); + ROUTE_IMPORT(SendConsoleCommand, G_SEND_CONSOLE_COMMAND); + ROUTE_IMPORT(SendServerCommand, G_SEND_SERVER_COMMAND); + ROUTE_IMPORT(SetBrushModel, G_SET_BRUSH_MODEL); + ROUTE_IMPORT(SetConfigstring, G_SET_CONFIGSTRING); + ROUTE_IMPORT(SetServerCull, G_SET_SERVER_CULL); + ROUTE_IMPORT(SetUserinfo, G_SET_USERINFO); + ROUTE_IMPORT(SiegePersSet, G_SIEGEPERSSET); + ROUTE_IMPORT(SiegePersGet, G_SIEGEPERSGET); + ROUTE_IMPORT(Trace, G_TRACE); + ROUTE_IMPORT(UnlinkEntity, G_UNLINKENTITY); + ROUTE_IMPORT(ROFF_Clean, G_ROFF_CLEAN); + ROUTE_IMPORT(ROFF_UpdateEntities, G_ROFF_UPDATE_ENTITIES); + ROUTE_IMPORT(ROFF_Cache, G_ROFF_CACHE); + ROUTE_IMPORT(ROFF_Play, G_ROFF_PLAY); + ROUTE_IMPORT(ROFF_Purge_Ent, G_ROFF_PURGE_ENT); + ROUTE_IMPORT(ICARUS_RunScript, G_ICARUS_RUNSCRIPT); + ROUTE_IMPORT(ICARUS_RegisterScript, G_ICARUS_REGISTERSCRIPT); + ROUTE_IMPORT(ICARUS_Init, G_ICARUS_INIT); + ROUTE_IMPORT(ICARUS_ValidEnt, G_ICARUS_VALIDENT); + ROUTE_IMPORT(ICARUS_IsInitialized, G_ICARUS_ISINITIALIZED); + ROUTE_IMPORT(ICARUS_MaintainTaskManager, G_ICARUS_MAINTAINTASKMANAGER); + ROUTE_IMPORT(ICARUS_IsRunning, G_ICARUS_ISRUNNING); + ROUTE_IMPORT(ICARUS_TaskIDPending, G_ICARUS_TASKIDPENDING); + ROUTE_IMPORT(ICARUS_InitEnt, G_ICARUS_INITENT); + ROUTE_IMPORT(ICARUS_FreeEnt, G_ICARUS_FREEENT); + ROUTE_IMPORT(ICARUS_AssociateEnt, G_ICARUS_ASSOCIATEENT); + ROUTE_IMPORT(ICARUS_Shutdown, G_ICARUS_SHUTDOWN); + ROUTE_IMPORT(ICARUS_TaskIDSet, G_ICARUS_TASKIDSET); + ROUTE_IMPORT(ICARUS_TaskIDComplete, G_ICARUS_TASKIDCOMPLETE); + ROUTE_IMPORT(ICARUS_SetVar, G_ICARUS_SETVAR); + ROUTE_IMPORT(ICARUS_VariableDeclared, G_ICARUS_VARIABLEDECLARED); + ROUTE_IMPORT(ICARUS_GetFloatVariable, G_ICARUS_GETFLOATVARIABLE); + ROUTE_IMPORT(ICARUS_GetStringVariable, G_ICARUS_GETSTRINGVARIABLE); + ROUTE_IMPORT(ICARUS_GetVectorVariable, G_ICARUS_GETVECTORVARIABLE); + ROUTE_IMPORT(Nav_Init, G_NAV_INIT); + ROUTE_IMPORT(Nav_Free, G_NAV_FREE); + ROUTE_IMPORT(Nav_Load, G_NAV_LOAD); + ROUTE_IMPORT(Nav_Save, G_NAV_SAVE); + ROUTE_IMPORT(Nav_AddRawPoint, G_NAV_ADDRAWPOINT); + ROUTE_IMPORT(Nav_CalculatePaths, G_NAV_CALCULATEPATHS); + ROUTE_IMPORT(Nav_HardConnect, G_NAV_HARDCONNECT); + ROUTE_IMPORT(Nav_ShowNodes, G_NAV_SHOWNODES); + ROUTE_IMPORT(Nav_ShowEdges, G_NAV_SHOWEDGES); + ROUTE_IMPORT(Nav_ShowPath, G_NAV_SHOWPATH); + ROUTE_IMPORT(Nav_GetNearestNode, G_NAV_GETNEARESTNODE); + ROUTE_IMPORT(Nav_GetBestNode, G_NAV_GETBESTNODE); + ROUTE_IMPORT(Nav_GetNodePosition, G_NAV_GETNODEPOSITION); + ROUTE_IMPORT(Nav_GetNodeNumEdges, G_NAV_GETNODENUMEDGES); + ROUTE_IMPORT(Nav_GetNodeEdge, G_NAV_GETNODEEDGE); + ROUTE_IMPORT(Nav_GetNumNodes, G_NAV_GETNUMNODES); + ROUTE_IMPORT(Nav_Connected, G_NAV_CONNECTED); + ROUTE_IMPORT(Nav_GetPathCost, G_NAV_GETPATHCOST); + ROUTE_IMPORT(Nav_GetEdgeCost, G_NAV_GETEDGECOST); + ROUTE_IMPORT(Nav_GetProjectedNode, G_NAV_GETPROJECTEDNODE); + ROUTE_IMPORT(Nav_CheckFailedNodes, G_NAV_CHECKFAILEDNODES); + ROUTE_IMPORT(Nav_AddFailedNode, G_NAV_ADDFAILEDNODE); + ROUTE_IMPORT(Nav_NodeFailed, G_NAV_NODEFAILED); + ROUTE_IMPORT(Nav_NodesAreNeighbors, G_NAV_NODESARENEIGHBORS); + ROUTE_IMPORT(Nav_ClearFailedEdge, G_NAV_CLEARFAILEDEDGE); + ROUTE_IMPORT(Nav_ClearAllFailedEdges, G_NAV_CLEARALLFAILEDEDGES); + ROUTE_IMPORT(Nav_EdgeFailed, G_NAV_EDGEFAILED); + ROUTE_IMPORT(Nav_AddFailedEdge, G_NAV_ADDFAILEDEDGE); + ROUTE_IMPORT(Nav_CheckFailedEdge, G_NAV_CHECKFAILEDEDGE); + ROUTE_IMPORT(Nav_CheckAllFailedEdges, G_NAV_CHECKALLFAILEDEDGES); + ROUTE_IMPORT(Nav_RouteBlocked, G_NAV_ROUTEBLOCKED); + ROUTE_IMPORT(Nav_GetBestNodeAltRoute, G_NAV_GETBESTNODEALTROUTE); + ROUTE_IMPORT(Nav_GetBestNodeAltRoute2, G_NAV_GETBESTNODEALT2); + ROUTE_IMPORT(Nav_GetBestPathBetweenEnts, G_NAV_GETBESTPATHBETWEENENTS); + ROUTE_IMPORT(Nav_GetNodeRadius, G_NAV_GETNODERADIUS); + ROUTE_IMPORT(Nav_CheckBlockedEdges, G_NAV_CHECKBLOCKEDEDGES); + ROUTE_IMPORT(Nav_ClearCheckedNodes, G_NAV_CLEARCHECKEDNODES); + ROUTE_IMPORT(Nav_CheckedNode, G_NAV_CHECKEDNODE); + ROUTE_IMPORT(Nav_SetCheckedNode, G_NAV_SETCHECKEDNODE); + ROUTE_IMPORT(Nav_FlagAllNodes, G_NAV_FLAGALLNODES); + ROUTE_IMPORT(Nav_GetPathsCalculated, G_NAV_GETPATHSCALCULATED); + ROUTE_IMPORT(Nav_SetPathsCalculated, G_NAV_SETPATHSCALCULATED); + ROUTE_IMPORT(BotAllocateClient, G_BOT_ALLOCATE_CLIENT); + ROUTE_IMPORT(BotFreeClient, G_BOT_FREE_CLIENT); + ROUTE_IMPORT(BotLoadCharacter, BOTLIB_AI_LOAD_CHARACTER); + ROUTE_IMPORT(BotFreeCharacter, BOTLIB_AI_FREE_CHARACTER); + ROUTE_IMPORT(Characteristic_Float, BOTLIB_AI_CHARACTERISTIC_FLOAT); + ROUTE_IMPORT(Characteristic_BFloat, BOTLIB_AI_CHARACTERISTIC_BFLOAT); + ROUTE_IMPORT(Characteristic_Integer, BOTLIB_AI_CHARACTERISTIC_INTEGER); + ROUTE_IMPORT(Characteristic_BInteger, BOTLIB_AI_CHARACTERISTIC_BINTEGER); + ROUTE_IMPORT(Characteristic_String, BOTLIB_AI_CHARACTERISTIC_STRING); + ROUTE_IMPORT(BotAllocChatState, BOTLIB_AI_ALLOC_CHAT_STATE); + ROUTE_IMPORT(BotFreeChatState, BOTLIB_AI_FREE_CHAT_STATE); + ROUTE_IMPORT(BotQueueConsoleMessage, BOTLIB_AI_QUEUE_CONSOLE_MESSAGE); + ROUTE_IMPORT(BotRemoveConsoleMessage, BOTLIB_AI_REMOVE_CONSOLE_MESSAGE); + ROUTE_IMPORT(BotNextConsoleMessage, BOTLIB_AI_NEXT_CONSOLE_MESSAGE); + ROUTE_IMPORT(BotNumConsoleMessages, BOTLIB_AI_NUM_CONSOLE_MESSAGE); + ROUTE_IMPORT(BotInitialChat, BOTLIB_AI_INITIAL_CHAT); + ROUTE_IMPORT(BotReplyChat, BOTLIB_AI_REPLY_CHAT); + ROUTE_IMPORT(BotChatLength, BOTLIB_AI_CHAT_LENGTH); + ROUTE_IMPORT(BotEnterChat, BOTLIB_AI_ENTER_CHAT); + ROUTE_IMPORT(StringContains, BOTLIB_AI_STRING_CONTAINS); + ROUTE_IMPORT(BotFindMatch, BOTLIB_AI_FIND_MATCH); + ROUTE_IMPORT(BotMatchVariable, BOTLIB_AI_MATCH_VARIABLE); + ROUTE_IMPORT(UnifyWhiteSpaces, BOTLIB_AI_UNIFY_WHITE_SPACES); + ROUTE_IMPORT(BotReplaceSynonyms, BOTLIB_AI_REPLACE_SYNONYMS); + ROUTE_IMPORT(BotLoadChatFile, BOTLIB_AI_LOAD_CHAT_FILE); + ROUTE_IMPORT(BotSetChatGender, BOTLIB_AI_SET_CHAT_GENDER); + ROUTE_IMPORT(BotSetChatName, BOTLIB_AI_SET_CHAT_NAME); + ROUTE_IMPORT(BotResetGoalState, BOTLIB_AI_RESET_GOAL_STATE); + ROUTE_IMPORT(BotResetAvoidGoals, BOTLIB_AI_RESET_AVOID_GOALS); + ROUTE_IMPORT(BotPushGoal, BOTLIB_AI_PUSH_GOAL); + ROUTE_IMPORT(BotPopGoal, BOTLIB_AI_POP_GOAL); + ROUTE_IMPORT(BotEmptyGoalStack, BOTLIB_AI_EMPTY_GOAL_STACK); + ROUTE_IMPORT(BotDumpAvoidGoals, BOTLIB_AI_DUMP_AVOID_GOALS); + ROUTE_IMPORT(BotDumpGoalStack, BOTLIB_AI_DUMP_GOAL_STACK); + ROUTE_IMPORT(BotGoalName, BOTLIB_AI_GOAL_NAME); + ROUTE_IMPORT(BotGetTopGoal, BOTLIB_AI_GET_TOP_GOAL); + ROUTE_IMPORT(BotGetSecondGoal, BOTLIB_AI_GET_SECOND_GOAL); + ROUTE_IMPORT(BotChooseLTGItem, BOTLIB_AI_CHOOSE_LTG_ITEM); + ROUTE_IMPORT(BotChooseNBGItem, BOTLIB_AI_CHOOSE_NBG_ITEM); + ROUTE_IMPORT(BotTouchingGoal, BOTLIB_AI_TOUCHING_GOAL); + ROUTE_IMPORT(BotItemGoalInVisButNotVisible, BOTLIB_AI_ITEM_GOAL_IN_VIS_BUT_NOT_VISIBLE); + ROUTE_IMPORT(BotGetLevelItemGoal, BOTLIB_AI_GET_LEVEL_ITEM_GOAL); + ROUTE_IMPORT(BotAvoidGoalTime, BOTLIB_AI_AVOID_GOAL_TIME); + ROUTE_IMPORT(BotInitLevelItems, BOTLIB_AI_INIT_LEVEL_ITEMS); + ROUTE_IMPORT(BotUpdateEntityItems, BOTLIB_AI_UPDATE_ENTITY_ITEMS); + ROUTE_IMPORT(BotLoadItemWeights, BOTLIB_AI_LOAD_ITEM_WEIGHTS); + ROUTE_IMPORT(BotFreeItemWeights, BOTLIB_AI_FREE_ITEM_WEIGHTS); + ROUTE_IMPORT(BotSaveGoalFuzzyLogic, BOTLIB_AI_SAVE_GOAL_FUZZY_LOGIC); + ROUTE_IMPORT(BotAllocGoalState, BOTLIB_AI_ALLOC_GOAL_STATE); + ROUTE_IMPORT(BotFreeGoalState, BOTLIB_AI_FREE_GOAL_STATE); + ROUTE_IMPORT(BotResetMoveState, BOTLIB_AI_RESET_MOVE_STATE); + ROUTE_IMPORT(BotMoveToGoal, BOTLIB_AI_MOVE_TO_GOAL); + ROUTE_IMPORT(BotMoveInDirection, BOTLIB_AI_MOVE_IN_DIRECTION); + ROUTE_IMPORT(BotResetAvoidReach, BOTLIB_AI_RESET_AVOID_REACH); + ROUTE_IMPORT(BotResetLastAvoidReach, BOTLIB_AI_RESET_LAST_AVOID_REACH); + ROUTE_IMPORT(BotReachabilityArea, BOTLIB_AI_REACHABILITY_AREA); + ROUTE_IMPORT(BotMovementViewTarget, BOTLIB_AI_MOVEMENT_VIEW_TARGET); + ROUTE_IMPORT(BotAllocMoveState, BOTLIB_AI_ALLOC_MOVE_STATE); + ROUTE_IMPORT(BotFreeMoveState, BOTLIB_AI_FREE_MOVE_STATE); + ROUTE_IMPORT(BotInitMoveState, BOTLIB_AI_INIT_MOVE_STATE); + ROUTE_IMPORT(BotChooseBestFightWeapon, BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON); + ROUTE_IMPORT(BotGetWeaponInfo, BOTLIB_AI_GET_WEAPON_INFO); + ROUTE_IMPORT(BotLoadWeaponWeights, BOTLIB_AI_LOAD_WEAPON_WEIGHTS); + ROUTE_IMPORT(BotAllocWeaponState, BOTLIB_AI_ALLOC_WEAPON_STATE); + ROUTE_IMPORT(BotFreeWeaponState, BOTLIB_AI_FREE_WEAPON_STATE); + ROUTE_IMPORT(BotResetWeaponState, BOTLIB_AI_RESET_WEAPON_STATE); + ROUTE_IMPORT(GeneticParentsAndChildSelection, BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION); + ROUTE_IMPORT(BotInterbreedGoalFuzzyLogic, BOTLIB_AI_INTERBREED_GOAL_FUZZY_LOGIC); + ROUTE_IMPORT(BotMutateGoalFuzzyLogic, BOTLIB_AI_MUTATE_GOAL_FUZZY_LOGIC); + ROUTE_IMPORT(BotGetNextCampSpotGoal, BOTLIB_AI_GET_NEXT_CAMP_SPOT_GOAL); + ROUTE_IMPORT(BotGetMapLocationGoal, BOTLIB_AI_GET_MAP_LOCATION_GOAL); + ROUTE_IMPORT(BotNumInitialChats, BOTLIB_AI_NUM_INITIAL_CHATS); + ROUTE_IMPORT(BotGetChatMessage, BOTLIB_AI_GET_CHAT_MESSAGE); + ROUTE_IMPORT(BotRemoveFromAvoidGoals, BOTLIB_AI_REMOVE_FROM_AVOID_GOALS); + ROUTE_IMPORT(BotPredictVisiblePosition, BOTLIB_AI_PREDICT_VISIBLE_POSITION); + ROUTE_IMPORT(BotSetAvoidGoalTime, BOTLIB_AI_SET_AVOID_GOAL_TIME); + ROUTE_IMPORT(BotAddAvoidSpot, BOTLIB_AI_ADD_AVOID_SPOT); + ROUTE_IMPORT(BotLibSetup, BOTLIB_SETUP); + ROUTE_IMPORT(BotLibShutdown, BOTLIB_SHUTDOWN); + ROUTE_IMPORT(BotLibVarSet, BOTLIB_LIBVAR_SET); + ROUTE_IMPORT(BotLibVarGet, BOTLIB_LIBVAR_GET); + ROUTE_IMPORT(BotLibDefine, BOTLIB_PC_ADD_GLOBAL_DEFINE); + ROUTE_IMPORT(BotLibStartFrame, BOTLIB_START_FRAME); + ROUTE_IMPORT(BotLibLoadMap, BOTLIB_LOAD_MAP); + ROUTE_IMPORT(BotLibUpdateEntity, BOTLIB_UPDATENTITY); + ROUTE_IMPORT(BotLibTest, BOTLIB_TEST); + ROUTE_IMPORT(BotGetSnapshotEntity, BOTLIB_GET_SNAPSHOT_ENTITY); + ROUTE_IMPORT(BotGetServerCommand, BOTLIB_GET_CONSOLE_MESSAGE); + ROUTE_IMPORT(BotUserCommand, BOTLIB_USER_COMMAND); + ROUTE_IMPORT(BotUpdateWaypoints, G_BOT_UPDATEWAYPOINTS); + ROUTE_IMPORT(BotCalculatePaths, G_BOT_CALCULATEPATHS); + ROUTE_IMPORT(AAS_EnableRoutingArea, BOTLIB_AAS_ENABLE_ROUTING_AREA); + ROUTE_IMPORT(AAS_BBoxAreas, BOTLIB_AAS_BBOX_AREAS); + ROUTE_IMPORT(AAS_AreaInfo, BOTLIB_AAS_AREA_INFO); + ROUTE_IMPORT(AAS_EntityInfo, BOTLIB_AAS_ENTITY_INFO); + ROUTE_IMPORT(AAS_Initialized, BOTLIB_AAS_INITIALIZED); + ROUTE_IMPORT(AAS_PresenceTypeBoundingBox, BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX); + ROUTE_IMPORT(AAS_Time, BOTLIB_AAS_TIME); + ROUTE_IMPORT(AAS_PointAreaNum, BOTLIB_AAS_POINT_AREA_NUM); + ROUTE_IMPORT(AAS_TraceAreas, BOTLIB_AAS_TRACE_AREAS); + ROUTE_IMPORT(AAS_PointContents, BOTLIB_AAS_POINT_CONTENTS); + ROUTE_IMPORT(AAS_NextBSPEntity, BOTLIB_AAS_NEXT_BSP_ENTITY); + ROUTE_IMPORT(AAS_ValueForBSPEpairKey, BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY); + ROUTE_IMPORT(AAS_VectorForBSPEpairKey, BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY); + ROUTE_IMPORT(AAS_FloatForBSPEpairKey, BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY); + ROUTE_IMPORT(AAS_IntForBSPEpairKey, BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY); + ROUTE_IMPORT(AAS_AreaReachability, BOTLIB_AAS_AREA_REACHABILITY); + ROUTE_IMPORT(AAS_AreaTravelTimeToGoalArea, BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA); + ROUTE_IMPORT(AAS_Swimming, BOTLIB_AAS_SWIMMING); + ROUTE_IMPORT(AAS_PredictClientMovement, BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT); + ROUTE_IMPORT(AAS_AlternativeRouteGoals, BOTLIB_AAS_ALTERNATIVE_ROUTE_GOAL); + ROUTE_IMPORT(AAS_PredictRoute, BOTLIB_AAS_PREDICT_ROUTE); + ROUTE_IMPORT(AAS_PointReachabilityAreaIndex, BOTLIB_AAS_POINT_REACHABILITY_AREA_INDEX); + ROUTE_IMPORT(EA_Say, BOTLIB_EA_SAY); + ROUTE_IMPORT(EA_SayTeam, BOTLIB_EA_SAY_TEAM); + ROUTE_IMPORT(EA_Command, BOTLIB_EA_COMMAND); + ROUTE_IMPORT(EA_Action, BOTLIB_EA_ACTION); + ROUTE_IMPORT(EA_Gesture, BOTLIB_EA_GESTURE); + ROUTE_IMPORT(EA_Talk, BOTLIB_EA_TALK); + ROUTE_IMPORT(EA_Attack, BOTLIB_EA_ATTACK); + ROUTE_IMPORT(EA_Alt_Attack, BOTLIB_EA_ALT_ATTACK); + ROUTE_IMPORT(EA_ForcePower, BOTLIB_EA_FORCEPOWER); + ROUTE_IMPORT(EA_Use, BOTLIB_EA_USE); + ROUTE_IMPORT(EA_Respawn, BOTLIB_EA_RESPAWN); + ROUTE_IMPORT(EA_Crouch, BOTLIB_EA_CROUCH); + ROUTE_IMPORT(EA_MoveUp, BOTLIB_EA_MOVE_UP); + ROUTE_IMPORT(EA_MoveDown, BOTLIB_EA_MOVE_DOWN); + ROUTE_IMPORT(EA_MoveForward, BOTLIB_EA_MOVE_FORWARD); + ROUTE_IMPORT(EA_MoveBack, BOTLIB_EA_MOVE_BACK); + ROUTE_IMPORT(EA_MoveLeft, BOTLIB_EA_MOVE_LEFT); + ROUTE_IMPORT(EA_MoveRight, BOTLIB_EA_MOVE_RIGHT); + ROUTE_IMPORT(EA_SelectWeapon, BOTLIB_EA_SELECT_WEAPON); + ROUTE_IMPORT(EA_Jump, BOTLIB_EA_JUMP); + ROUTE_IMPORT(EA_DelayedJump, BOTLIB_EA_DELAYED_JUMP); + ROUTE_IMPORT(EA_Move, BOTLIB_EA_MOVE); + ROUTE_IMPORT(EA_View, BOTLIB_EA_VIEW); + ROUTE_IMPORT(EA_EndRegular, BOTLIB_EA_END_REGULAR); + ROUTE_IMPORT(EA_GetInput, BOTLIB_EA_GET_INPUT); + ROUTE_IMPORT(EA_ResetInput, BOTLIB_EA_RESET_INPUT); + ROUTE_IMPORT(PC_LoadSource, BOTLIB_PC_LOAD_SOURCE); + ROUTE_IMPORT(PC_FreeSource, BOTLIB_PC_FREE_SOURCE); + ROUTE_IMPORT(PC_ReadToken, BOTLIB_PC_READ_TOKEN); + ROUTE_IMPORT(PC_SourceFileAndLine, BOTLIB_PC_SOURCE_FILE_AND_LINE); + ROUTE_IMPORT(R_RegisterSkin, G_R_REGISTERSKIN); + ROUTE_IMPORT(SetActiveSubBSP, G_SET_ACTIVE_SUBBSP); + ROUTE_IMPORT(CM_RegisterTerrain, G_CM_REGISTER_TERRAIN); + ROUTE_IMPORT(RMG_Init, G_RMG_INIT); + ROUTE_IMPORT(G2API_ListModelBones, G_G2_LISTBONES); + ROUTE_IMPORT(G2API_ListModelSurfaces, G_G2_LISTSURFACES); + ROUTE_IMPORT(G2API_HaveWeGhoul2Models, G_G2_HAVEWEGHOULMODELS); + ROUTE_IMPORT(G2API_SetGhoul2ModelIndexes, G_G2_SETMODELS); + ROUTE_IMPORT(G2API_GetBoltMatrix, G_G2_GETBOLT); + ROUTE_IMPORT(G2API_GetBoltMatrix_NoReconstruct, G_G2_GETBOLT_NOREC); + ROUTE_IMPORT(G2API_GetBoltMatrix_NoRecNoRot, G_G2_GETBOLT_NOREC_NOROT); + ROUTE_IMPORT(G2API_InitGhoul2Model, G_G2_INITGHOUL2MODEL); + ROUTE_IMPORT(G2API_SetSkin, G_G2_SETSKIN); + ROUTE_IMPORT(G2API_Ghoul2Size, G_G2_SIZE); + ROUTE_IMPORT(G2API_AddBolt, G_G2_ADDBOLT); + ROUTE_IMPORT(G2API_SetBoltInfo, G_G2_SETBOLTINFO); + ROUTE_IMPORT(G2API_SetBoneAngles, G_G2_ANGLEOVERRIDE); + ROUTE_IMPORT(G2API_SetBoneAnim, G_G2_PLAYANIM); + ROUTE_IMPORT(G2API_GetBoneAnim, G_G2_GETBONEANIM); + ROUTE_IMPORT(G2API_GetGLAName, G_G2_GETGLANAME); + ROUTE_IMPORT(G2API_CopyGhoul2Instance, G_G2_COPYGHOUL2INSTANCE); + ROUTE_IMPORT(G2API_CopySpecificGhoul2Model, G_G2_COPYSPECIFICGHOUL2MODEL); + ROUTE_IMPORT(G2API_DuplicateGhoul2Instance, G_G2_DUPLICATEGHOUL2INSTANCE); + ROUTE_IMPORT(G2API_HasGhoul2ModelOnIndex, G_G2_HASGHOUL2MODELONINDEX); + ROUTE_IMPORT(G2API_RemoveGhoul2Model, G_G2_REMOVEGHOUL2MODEL); + ROUTE_IMPORT(G2API_RemoveGhoul2Models, G_G2_REMOVEGHOUL2MODELS); + ROUTE_IMPORT(G2API_CleanGhoul2Models, G_G2_CLEANMODELS); + ROUTE_IMPORT(G2API_CollisionDetect, G_G2_COLLISIONDETECT); + ROUTE_IMPORT(G2API_CollisionDetectCache, G_G2_COLLISIONDETECTCACHE); + ROUTE_IMPORT(G2API_SetRootSurface, G_G2_SETROOTSURFACE); + ROUTE_IMPORT(G2API_SetSurfaceOnOff, G_G2_SETSURFACEONOFF); + ROUTE_IMPORT(G2API_SetNewOrigin, G_G2_SETNEWORIGIN); + ROUTE_IMPORT(G2API_DoesBoneExist, G_G2_DOESBONEEXIST); + ROUTE_IMPORT(G2API_GetSurfaceRenderStatus, G_G2_GETSURFACERENDERSTATUS); + ROUTE_IMPORT(G2API_AbsurdSmoothing, G_G2_ABSURDSMOOTHING); + ROUTE_IMPORT(G2API_SetRagDoll, G_G2_SETRAGDOLL); + ROUTE_IMPORT(G2API_AnimateG2Models, G_G2_ANIMATEG2MODELS); + ROUTE_IMPORT(G2API_RagPCJConstraint, G_G2_RAGPCJCONSTRAINT); + ROUTE_IMPORT(G2API_RagPCJGradientSpeed, G_G2_RAGPCJGRADIENTSPEED); + ROUTE_IMPORT(G2API_RagEffectorGoal, G_G2_RAGEFFECTORGOAL); + ROUTE_IMPORT(G2API_GetRagBonePos, G_G2_GETRAGBONEPOS); + ROUTE_IMPORT(G2API_RagEffectorKick, G_G2_RAGEFFECTORKICK); + ROUTE_IMPORT(G2API_RagForceSolve, G_G2_RAGFORCESOLVE); + ROUTE_IMPORT(G2API_SetBoneIKState, G_G2_SETBONEIKSTATE); + ROUTE_IMPORT(G2API_IKMove, G_G2_IKMOVE); + ROUTE_IMPORT(G2API_RemoveBone, G_G2_REMOVEBONE); + ROUTE_IMPORT(G2API_AttachInstanceToEntNum, G_G2_ATTACHINSTANCETOENTNUM); + ROUTE_IMPORT(G2API_ClearAttachedInstance, G_G2_CLEARATTACHEDINSTANCE); + ROUTE_IMPORT(G2API_CleanEntAttachments, G_G2_CLEANENTATTACHMENTS); + ROUTE_IMPORT(G2API_OverrideServer, G_G2_OVERRIDESERVER); + ROUTE_IMPORT(G2API_GetSurfaceName, G_G2_GETSURFACENAME); default: break; @@ -251,6 +904,45 @@ static intptr_t JAMP_vmMain_GGA(intptr_t cmd, ...) { switch (cmd) { ROUTE_EXPORT(InitGame, GAME_INIT); + ROUTE_EXPORT(ShutdownGame, GAME_SHUTDOWN); + ROUTE_EXPORT(ClientConnect, GAME_CLIENT_CONNECT); + ROUTE_EXPORT(ClientBegin, GAME_CLIENT_BEGIN); + ROUTE_EXPORT(ClientUserinfoChanged, GAME_CLIENT_USERINFO_CHANGED); + ROUTE_EXPORT(ClientDisconnect, GAME_CLIENT_DISCONNECT); + ROUTE_EXPORT(ClientCommand, GAME_CLIENT_COMMAND); + ROUTE_EXPORT(ClientThink, GAME_CLIENT_THINK); + ROUTE_EXPORT(RunFrame, GAME_RUN_FRAME); + ROUTE_EXPORT(ConsoleCommand, GAME_CONSOLE_COMMAND); + ROUTE_EXPORT(BotAIStartFrame, BOTAI_START_FRAME); + ROUTE_EXPORT(ROFF_NotetrackCallback, GAME_ROFF_NOTETRACK_CALLBACK); + ROUTE_EXPORT(SpawnRMGEntity, GAME_SPAWN_RMG_ENTITY); + ROUTE_EXPORT(ICARUS_PlaySound, GAME_ICARUS_PLAYSOUND); + ROUTE_EXPORT(ICARUS_Set, GAME_ICARUS_SET); + ROUTE_EXPORT(ICARUS_Lerp2Pos, GAME_ICARUS_LERP2POS); + ROUTE_EXPORT(ICARUS_Lerp2Origin, GAME_ICARUS_LERP2ORIGIN); + ROUTE_EXPORT(ICARUS_Lerp2Angles, GAME_ICARUS_LERP2ANGLES); + ROUTE_EXPORT(ICARUS_GetTag, GAME_ICARUS_GETTAG); + ROUTE_EXPORT(ICARUS_Lerp2Start, GAME_ICARUS_LERP2START); + ROUTE_EXPORT(ICARUS_Lerp2End, GAME_ICARUS_LERP2END); + ROUTE_EXPORT(ICARUS_Use, GAME_ICARUS_USE); + ROUTE_EXPORT(ICARUS_Kill, GAME_ICARUS_KILL); + ROUTE_EXPORT(ICARUS_Remove, GAME_ICARUS_REMOVE); + ROUTE_EXPORT(ICARUS_Play, GAME_ICARUS_PLAY); + ROUTE_EXPORT(ICARUS_GetFloat, GAME_ICARUS_GETFLOAT); + ROUTE_EXPORT(ICARUS_GetVector, GAME_ICARUS_GETVECTOR); + ROUTE_EXPORT(ICARUS_GetString, GAME_ICARUS_GETSTRING); + ROUTE_EXPORT(ICARUS_SoundIndex, GAME_ICARUS_SOUNDINDEX); + ROUTE_EXPORT(ICARUS_GetSetIDForString, GAME_ICARUS_GETSETIDFORSTRING); + ROUTE_EXPORT(NAV_ClearPathToPoint, GAME_NAV_CLEARPATHTOPOINT); + ROUTE_EXPORT(NPC_ClearLOS2, GAME_NAV_CLEARLOS); + ROUTE_EXPORT(NAVNEW_ClearPathBetweenPoints, GAME_NAV_CLEARPATHBETWEENPOINTS); + ROUTE_EXPORT(NAV_CheckNodeFailedForEnt, GAME_NAV_CHECKNODEFAILEDFORENT); + ROUTE_EXPORT(NAV_EntIsUnlockedDoor, GAME_NAV_ENTISUNLOCKEDDOOR); + ROUTE_EXPORT(NAV_EntIsDoor, GAME_NAV_ENTISDOOR); + ROUTE_EXPORT(NAV_EntIsBreakable, GAME_NAV_ENTISBREAKABLE); + ROUTE_EXPORT(NAV_EntIsRemovableUsable, GAME_NAV_ENTISREMOVABLEUSABLE); + ROUTE_EXPORT(NAV_FindCombatPointWaypoints, GAME_NAV_FINDCOMBATPOINTWAYPOINTS); + ROUTE_EXPORT(BG_GetItemIndexByTag, GAME_GETITEMINDEXBYTAG); default: break; @@ -647,6 +1339,12 @@ static const char* JAMP_eng_msg_names(intptr_t cmd) { GEN_CASE(G_RMG_INIT); GEN_CASE(G_BOT_UPDATEWAYPOINTS); GEN_CASE(G_BOT_CALCULATEPATHS); + + // OpenJK-only + GEN_CASE(G_SV_REGISTER_SHARED_MEMORY); + + // polyfills + GEN_CASE(G_ARGS); default: return "unknown"; } @@ -696,9 +1394,6 @@ static const char* JAMP_mod_msg_names(intptr_t cmd) { GEN_CASE(GAME_NAV_FINDCOMBATPOINTWAYPOINTS); GEN_CASE(GAME_GETITEMINDEXBYTAG); - // polyfills - GEN_CASE(G_ARGS); - default: return "unknown"; } From 868c69ab5d302432f3aae28fd0960d2201ec58c5 Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 20:50:06 +0200 Subject: [PATCH 07/12] fix bug in G_ARGS polyfill --- src/game_cod11mp.cpp | 6 +++--- src/game_codmp.cpp | 4 ++-- src/game_coduomp.cpp | 4 ++-- src/game_jasp.cpp | 2 +- src/game_jk2mp.cpp | 4 ++-- src/game_jk2sp.cpp | 2 +- src/game_mohaa.cpp | 2 +- src/game_mohbt.cpp | 2 +- src/game_mohsh.cpp | 2 +- src/game_q2r.cpp | 2 +- src/game_q3a.cpp | 4 ++-- src/game_quake2.cpp | 2 +- src/game_rtcwmp.cpp | 4 ++-- src/game_rtcwsp.cpp | 4 ++-- src/game_sin.cpp | 2 +- src/game_sof2mp.cpp | 4 ++-- src/game_sof2sp.cpp | 2 +- src/game_stef2.cpp | 2 +- src/game_stvoyhm.cpp | 4 ++-- src/game_stvoysp.cpp | 2 +- src/game_wet.cpp | 4 ++-- 21 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/game_cod11mp.cpp b/src/game_cod11mp.cpp index c6b0f38..b076f03 100644 --- a/src/game_cod11mp.cpp +++ b/src/game_cod11mp.cpp @@ -23,7 +23,7 @@ GEN_EXTS(COD11MP); static const char* COD11MP_eng_msg_names(intptr_t); static const char* COD11MP_mod_msg_names(intptr_t); static void COD11MP_dllEntry(eng_syscall); -static bool COD11MP_mod_load(void*); +static bool COD11MP_mod_load(void*, bool); static void COD11MP_mod_unload(); supportedgame_funcs COD11MP_funcs = { COD11MP_qmm_eng_msgs, @@ -66,7 +66,7 @@ static intptr_t COD11MP_syscall(intptr_t cmd, ...) { s = ""; int i = 1; while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + orig_syscall(G_ARGV, i, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -134,7 +134,7 @@ static void COD11MP_dllEntry(eng_syscall syscall) { } -static bool COD11MP_mod_load(void* entry) { +static bool COD11MP_mod_load(void* entry, bool) { orig_vmMain = (mod_vmMain)entry; return !!orig_vmMain; diff --git a/src/game_codmp.cpp b/src/game_codmp.cpp index cfa5e7f..55841b7 100644 --- a/src/game_codmp.cpp +++ b/src/game_codmp.cpp @@ -71,7 +71,7 @@ static intptr_t CODMP_syscall(intptr_t cmd, ...) { s = ""; int i = 1; while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + orig_syscall(G_ARGV, i, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -139,7 +139,7 @@ static void CODMP_dllEntry(eng_syscall syscall) { } -static bool CODMP_mod_load(void* entry) { +static bool CODMP_mod_load(void* entry, bool) { orig_vmMain = (mod_vmMain)entry; return !!orig_vmMain; diff --git a/src/game_coduomp.cpp b/src/game_coduomp.cpp index 07fdda2..fecbb3e 100644 --- a/src/game_coduomp.cpp +++ b/src/game_coduomp.cpp @@ -71,7 +71,7 @@ static intptr_t CODUOMP_syscall(intptr_t cmd, ...) { s = ""; int i = 1; while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + orig_syscall(G_ARGV, i, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -139,7 +139,7 @@ static void CODUOMP_dllEntry(eng_syscall syscall) { } -static bool CODUOMP_mod_load(void* entry) { +static bool CODUOMP_mod_load(void* entry, bool) { orig_vmMain = (mod_vmMain)entry; return !!orig_vmMain; diff --git a/src/game_jasp.cpp b/src/game_jasp.cpp index 4dc33b3..11334dc 100644 --- a/src/game_jasp.cpp +++ b/src/game_jasp.cpp @@ -575,7 +575,7 @@ static void* JASP_GetGameAPI(void* import, void*) { } -static bool JASP_mod_load(void* entry) { +static bool JASP_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; orig_export = (game_export_t*)pfnGGA(&qmm_import, nullptr); diff --git a/src/game_jk2mp.cpp b/src/game_jk2mp.cpp index 2b092f4..0c80757 100644 --- a/src/game_jk2mp.cpp +++ b/src/game_jk2mp.cpp @@ -68,7 +68,7 @@ static intptr_t JK2MP_syscall(intptr_t cmd, ...) { s = ""; int i = 1; while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + orig_syscall(G_ARGV, i, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -142,7 +142,7 @@ static void JK2MP_dllEntry(eng_syscall syscall) { } -static bool JK2MP_mod_load(void* entry) { +static bool JK2MP_mod_load(void* entry, bool) { orig_vmMain = (mod_vmMain)entry; return !!orig_vmMain; diff --git a/src/game_jk2sp.cpp b/src/game_jk2sp.cpp index 2896bb3..57af74a 100644 --- a/src/game_jk2sp.cpp +++ b/src/game_jk2sp.cpp @@ -497,7 +497,7 @@ static void* JK2SP_GetGameAPI(void* import, void*) { } -static bool JK2SP_mod_load(void* entry) { +static bool JK2SP_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; orig_export = (game_export_t*)pfnGGA(&qmm_import, nullptr); diff --git a/src/game_mohaa.cpp b/src/game_mohaa.cpp index b9c0f38..0e16fb6 100644 --- a/src/game_mohaa.cpp +++ b/src/game_mohaa.cpp @@ -771,7 +771,7 @@ static void* MOHAA_GetGameAPI(void* import, void*) { } -static bool MOHAA_mod_load(void* entry) { +static bool MOHAA_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; orig_export = (game_export_t*)pfnGGA(&qmm_import, nullptr); diff --git a/src/game_mohbt.cpp b/src/game_mohbt.cpp index 503ec00..14de074 100644 --- a/src/game_mohbt.cpp +++ b/src/game_mohbt.cpp @@ -810,7 +810,7 @@ static void* MOHBT_GetGameAPI(void* import, void*) { } -static bool MOHBT_mod_load(void* entry) { +static bool MOHBT_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; orig_export = (game_export_t*)pfnGGA(&qmm_import, nullptr); diff --git a/src/game_mohsh.cpp b/src/game_mohsh.cpp index 6aea6de..d1d106c 100644 --- a/src/game_mohsh.cpp +++ b/src/game_mohsh.cpp @@ -810,7 +810,7 @@ static void* MOHSH_GetGameAPI(void* import, void*) { } -static bool MOHSH_mod_load(void* entry) { +static bool MOHSH_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; orig_export = (game_export_t*)pfnGGA(&qmm_import, nullptr); diff --git a/src/game_q2r.cpp b/src/game_q2r.cpp index 55b62b1..e60e99a 100644 --- a/src/game_q2r.cpp +++ b/src/game_q2r.cpp @@ -623,7 +623,7 @@ static void* Q2R_GetGameAPI(void* import, void*) { } -static bool Q2R_mod_load(void* entry) { +static bool Q2R_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; orig_export = (game_export_t*)pfnGGA(&qmm_import, nullptr); diff --git a/src/game_q3a.cpp b/src/game_q3a.cpp index 3125b84..1011782 100644 --- a/src/game_q3a.cpp +++ b/src/game_q3a.cpp @@ -68,7 +68,7 @@ static intptr_t Q3A_syscall(intptr_t cmd, ...) { s = ""; int i = 1; while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + orig_syscall(G_ARGV, i, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -141,7 +141,7 @@ static void Q3A_dllEntry(eng_syscall syscall) { } -static bool Q3A_mod_load(void* entry) { +static bool Q3A_mod_load(void* entry, bool) { orig_vmMain = (mod_vmMain)entry; return !!orig_vmMain; diff --git a/src/game_quake2.cpp b/src/game_quake2.cpp index 5f922dd..845322e 100644 --- a/src/game_quake2.cpp +++ b/src/game_quake2.cpp @@ -540,7 +540,7 @@ static void* QUAKE2_GetGameAPI(void* import, void*) { } -static bool QUAKE2_mod_load(void* entry) { +static bool QUAKE2_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; orig_export = (game_export_t*)pfnGGA(&qmm_import, nullptr); diff --git a/src/game_rtcwmp.cpp b/src/game_rtcwmp.cpp index f7dc57b..a7a8e7b 100644 --- a/src/game_rtcwmp.cpp +++ b/src/game_rtcwmp.cpp @@ -67,7 +67,7 @@ static intptr_t RTCWMP_syscall(intptr_t cmd, ...) { s = ""; int i = 1; while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + orig_syscall(G_ARGV, i, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -135,7 +135,7 @@ static void RTCWMP_dllEntry(eng_syscall syscall) { } -static bool RTCWMP_mod_load(void* entry) { +static bool RTCWMP_mod_load(void* entry, bool) { orig_vmMain = (mod_vmMain)entry; return !!orig_vmMain; diff --git a/src/game_rtcwsp.cpp b/src/game_rtcwsp.cpp index fab8999..55fec7d 100644 --- a/src/game_rtcwsp.cpp +++ b/src/game_rtcwsp.cpp @@ -67,7 +67,7 @@ static intptr_t RTCWSP_syscall(intptr_t cmd, ...) { s = ""; int i = 1; while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + orig_syscall(G_ARGV, i, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -135,7 +135,7 @@ static void RTCWSP_dllEntry(eng_syscall syscall) { } -static bool RTCWSP_mod_load(void* entry) { +static bool RTCWSP_mod_load(void* entry, bool) { orig_vmMain = (mod_vmMain)entry; return !!orig_vmMain; diff --git a/src/game_sin.cpp b/src/game_sin.cpp index 3c44a5c..decdc5e 100644 --- a/src/game_sin.cpp +++ b/src/game_sin.cpp @@ -657,7 +657,7 @@ static void* SIN_GetGameAPI(void* import, void*) { } -static bool SIN_mod_load(void* entry) { +static bool SIN_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; orig_export = (game_export_t*)pfnGGA(&qmm_import, nullptr); diff --git a/src/game_sof2mp.cpp b/src/game_sof2mp.cpp index 7d58dbd..6e3f16a 100644 --- a/src/game_sof2mp.cpp +++ b/src/game_sof2mp.cpp @@ -69,7 +69,7 @@ static intptr_t SOF2MP_syscall(intptr_t cmd, ...) { s = ""; int i = 1; while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + orig_syscall(G_ARGV, i, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -179,7 +179,7 @@ static void SOF2MP_dllEntry(eng_syscall syscall) { // get mod's vmMain function pointer from mod.cpp::mod_load -static bool SOF2MP_mod_load(void* entry) { +static bool SOF2MP_mod_load(void* entry, bool) { orig_vmMain = (mod_vmMain)entry; // we cannot verify data in the QVM since this engine both provides malloc functionality and has the gametype module, diff --git a/src/game_sof2sp.cpp b/src/game_sof2sp.cpp index 3c05041..8bee164 100644 --- a/src/game_sof2sp.cpp +++ b/src/game_sof2sp.cpp @@ -469,7 +469,7 @@ static void* SOF2SP_GetGameAPI(void* apiversion, void* import) { } -static bool SOF2SP_mod_load(void* entry) { +static bool SOF2SP_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; // api version gets passed before import pointer orig_export = (game_export_t*)pfnGGA((void*)orig_apiversion, &qmm_import); diff --git a/src/game_stef2.cpp b/src/game_stef2.cpp index 8f1ec7c..82c998b 100644 --- a/src/game_stef2.cpp +++ b/src/game_stef2.cpp @@ -985,7 +985,7 @@ static void* STEF2_GetGameAPI(void* import, void*) { } -static bool STEF2_mod_load(void* entry) { +static bool STEF2_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; orig_export = (game_export_t*)pfnGGA(&qmm_import, nullptr); diff --git a/src/game_stvoyhm.cpp b/src/game_stvoyhm.cpp index 9865f7d..fb24c5d 100644 --- a/src/game_stvoyhm.cpp +++ b/src/game_stvoyhm.cpp @@ -68,7 +68,7 @@ static intptr_t STVOYHM_syscall(intptr_t cmd, ...) { s = ""; int i = 1; while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + orig_syscall(G_ARGV, i, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -142,7 +142,7 @@ static void STVOYHM_dllEntry(eng_syscall syscall) { } -static bool STVOYHM_mod_load(void* entry) { +static bool STVOYHM_mod_load(void* entry, bool) { orig_vmMain = (mod_vmMain)entry; return !!orig_vmMain; diff --git a/src/game_stvoysp.cpp b/src/game_stvoysp.cpp index 545c7c2..e20d550 100644 --- a/src/game_stvoysp.cpp +++ b/src/game_stvoysp.cpp @@ -372,7 +372,7 @@ static void* STVOYSP_GetGameAPI(void* import, void*) { } -static bool STVOYSP_mod_load(void* entry) { +static bool STVOYSP_mod_load(void* entry, bool) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; orig_export = (game_export_t*)pfnGGA(&qmm_import, nullptr); diff --git a/src/game_wet.cpp b/src/game_wet.cpp index 512302f..93dd6f1 100644 --- a/src/game_wet.cpp +++ b/src/game_wet.cpp @@ -67,7 +67,7 @@ intptr_t WET_syscall(intptr_t cmd, ...) { s = ""; int i = 1; while (i < orig_syscall(G_ARGC)) { - orig_syscall(G_ARGV, buf, sizeof(buf)); + orig_syscall(G_ARGV, i, buf, sizeof(buf)); buf[sizeof(buf) - 1] = '\0'; if (i != 1) s += " "; @@ -135,7 +135,7 @@ void WET_dllEntry(eng_syscall syscall) { } -bool WET_mod_load(void* entry) { +bool WET_mod_load(void* entry, bool) { orig_vmMain = (mod_vmMain)entry; return !!orig_vmMain; From aca9f1b068c2f56ec8003cf5e6f39bce76dde293 Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 20:51:53 +0200 Subject: [PATCH 08/12] add is_GetGameAPI bool arg to game-specific mod_load function to let it know how it's being loaded. re-organize mod_load, remove s_mod_load_vmmain and s_mod_load_getgameapi functions. --- include/game_api.h | 8 +-- src/mod.cpp | 142 ++++++++++++++++++--------------------------- 2 files changed, 62 insertions(+), 88 deletions(-) diff --git a/include/game_api.h b/include/game_api.h index c7ea0d4..f58151c 100644 --- a/include/game_api.h +++ b/include/game_api.h @@ -30,7 +30,7 @@ struct supportedgame_funcs { qvm_syscall pfnqvmsyscall; // pointer to a function that handles mod->engine calls from a QVM (NULL = not supported) mod_dllEntry pfndllEntry; // pointer to a function that handles dllEntry entry for a game (NULL = not supported) mod_GetGameAPI pfnGetGameAPI; // pointer to a function that handles GetGameAPI entry for a game (NULL = not supported) - bool(*pfnModLoad)(void*); // pointer to a function that handles mod loading logic after a DLL is loaded + bool(*pfnModLoad)(void*, bool); // pointer to a function that handles mod loading logic after a DLL is loaded void(*pfnModUnload)(); // pointer to a function that handles mod unloading logic before a DLL is unloaded }; @@ -76,7 +76,7 @@ static intptr_t game##_syscall(intptr_t cmd, ...); \ static intptr_t game##_vmMain(intptr_t cmd, ...); \ static int game##_qvmsyscall(uint8_t*, int, int*); \ static void game##_dllEntry(eng_syscall); \ -static bool game##_mod_load(void*); \ +static bool game##_mod_load(void*, bool); \ static void game##_mod_unload(); \ supportedgame_funcs game##_funcs = { \ game##_qmm_eng_msgs, game##_qmm_mod_msgs, game##_eng_msg_names, game##_mod_msg_names, \ @@ -92,7 +92,7 @@ static bool game##_autodetect(bool, supportedgame*); \ static intptr_t game##_syscall(intptr_t cmd, ...); \ static intptr_t game##_vmMain(intptr_t cmd, ...); \ static void game##_dllEntry(eng_syscall); \ -static bool game##_mod_load(void*); \ +static bool game##_mod_load(void*, bool); \ static void game##_mod_unload(); \ supportedgame_funcs game##_funcs = { \ game##_qmm_eng_msgs, game##_qmm_mod_msgs, game##_eng_msg_names, game##_mod_msg_names, \ @@ -108,7 +108,7 @@ static bool game##_autodetect(bool, supportedgame*); \ static intptr_t game##_syscall(intptr_t cmd, ...); \ static intptr_t game##_vmMain(intptr_t cmd, ...); \ static void* game##_GetGameAPI(void*, void*); \ -static bool game##_mod_load(void*); \ +static bool game##_mod_load(void*, bool); \ static void game##_mod_unload(); \ supportedgame_funcs game##_funcs = { \ game##_qmm_eng_msgs, game##_qmm_mod_msgs, game##_eng_msg_names, game##_mod_msg_names, \ diff --git a/src/mod.cpp b/src/mod.cpp index aedc1a5..bf8dda8 100644 --- a/src/mod.cpp +++ b/src/mod.cpp @@ -28,8 +28,6 @@ mod g_mod; static intptr_t s_mod_qvm_vmmain(intptr_t cmd, ...); static int s_mod_qvm_syscall(uint8_t* membase, int cmd, int* args); static bool s_mod_load_qvm(mod& mod); -static bool s_mod_load_vmmain(mod& mod); -static bool s_mod_load_getgameapi(mod& mod); bool mod_load(mod& mod, std::string file) { @@ -54,23 +52,68 @@ bool mod_load(mod& mod, std::string file) { } // if this DLL is the same as QMM, cancel - if ((void*)mod.dll == g_gameinfo.qmm_module_ptr) { + if (mod.dll == g_gameinfo.qmm_module_ptr) { LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): DLL is actually QMM?\n", file); - mod_unload(mod); + dlclose(mod.dll); return false; } - - // pass off to engine-specific loading function - bool ret = false; - if (g_gameinfo.game->funcs->pfnGetGameAPI) - ret = s_mod_load_getgameapi(mod); + mod.vmbase = 0; + + // if game supports GetGameAPI, look for GetGameAPI function + if (g_gameinfo.game->funcs->pfnGetGameAPI) { + mod_GetGameAPI pfnGGA = (mod_GetGameAPI)dlsym(mod.dll, "GetGameAPI"); + + // try for "GetModuleAPI", which is what OpenJK uses + if (!pfnGGA) { + pfnGGA = (mod_GetGameAPI)dlsym(mod.dll, "GetModuleAPI"); + } + + if (pfnGGA) { + // pass the GetGameAPI function pointer to the game-specific mod load handler + if (g_gameinfo.game->funcs->pfnModLoad && + g_gameinfo.game->funcs->pfnModLoad((void*)pfnGGA, true)) { // true = is_GetGameAPI + return true; + } + else { + LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): \"GetGameAPI\" function failed\n", mod.path); + } + } + else { + LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): Unable to find \"GetGameAPI\" function\n", mod.path); + } + } - // fall back to vmmain loading if getgameapi failed - if (!ret) - return s_mod_load_vmmain(mod); + // if game supports dllEntry, look for dllEntry function + if (g_gameinfo.game->funcs->pfndllEntry) { + mod_dllEntry pfndllEntry = (mod_dllEntry)dlsym(mod.dll, "dllEntry"); + mod_vmMain pfnvmMain = (mod_vmMain)dlsym(mod.dll, "vmMain"); + + if (pfndllEntry && pfnvmMain) { + if (g_gameinfo.game->funcs->pfnModLoad) { + // pass the vmMain function pointer to the game-specific mod load handler + if (g_gameinfo.game->funcs->pfnModLoad((void*)pfnvmMain, false)) { // false = !is_GetGameAPI + // pass qmm_syscall to mod's dllEntry function + pfndllEntry(qmm_syscall); + return true; + } + else { + LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): Mod load failed?\n", mod.path); + } + } + // hack in case there isn't a game-specific dllEntry or ModLoad function + else if (!g_gameinfo.pfnvmMain) { + g_gameinfo.pfnvmMain = pfnvmMain; + } + } + else { + LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): Unable to find \"dllEntry\" and/or \"vmMain\" function\n", mod.path); + } + } } + mod_unload(mod); + LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): Unknown file format\n", file); return false; } @@ -175,7 +218,9 @@ static bool s_mod_load_qvm(mod& mod) { mod.vmbase = (intptr_t)mod.vm.datasegment; // pass the qvm vmMain function pointer to the game-specific mod load handler - if (g_gameinfo.game->funcs->pfnModLoad && !g_gameinfo.game->funcs->pfnModLoad((void*)s_mod_qvm_vmmain)) { + if (g_gameinfo.game->funcs->pfnModLoad && + !g_gameinfo.game->funcs->pfnModLoad((void*)s_mod_qvm_vmmain, false)) // false = !is_GetGameAPI + { LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): Mod load failed?\n", mod.path); goto fail; } @@ -191,74 +236,3 @@ static bool s_mod_load_qvm(mod& mod) { mod_unload(mod); return false; } - - -// load a GetGameAPI DLL mod -static bool s_mod_load_getgameapi(mod& mod) { - // look for GetGameAPI function - mod_GetGameAPI pfnGGA = (mod_GetGameAPI)dlsym(mod.dll, "GetGameAPI"); - - // try for "GetModuleAPI", which is what OpenJK uses - if (!pfnGGA) - pfnGGA = (mod_GetGameAPI)dlsym(mod.dll, "GetModuleAPI"); - - if (!pfnGGA) { - LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): Unable to find \"GetGameAPI\" function\n", mod.path); - goto fail; - } - - mod.vmbase = 0; - - // pass the GetGameAPI function pointer to the game-specific mod load handler - if (!g_gameinfo.game->funcs->pfnModLoad || !g_gameinfo.game->funcs->pfnModLoad((void*)pfnGGA)) { - LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): \"GetGameAPI\" function failed\n", mod.path); - goto fail; - } - - return true; - -fail: - mod_unload(mod); - return false; -} - - -// load a vmMain DLL mod -static bool s_mod_load_vmmain(mod& mod) { - mod_dllEntry pfndllEntry = nullptr; - mod_vmMain pfnvmMain = nullptr; - - // look for dllEntry function - if (!(pfndllEntry = (mod_dllEntry)dlsym(mod.dll, "dllEntry"))) { - LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): Unable to find \"dllEntry\" function\n", mod.path); - goto fail; - } - - // look for vmMain function - if (!(pfnvmMain = (mod_vmMain)dlsym(mod.dll, "vmMain"))) { - LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): Unable to find \"vmMain\" function\n", mod.path); - goto fail; - } - - // pass qmm_syscall to mod's dllEntry function - pfndllEntry(qmm_syscall); - - mod.vmbase = 0; - - // pass the vmMain function pointer to the game-specific mod load handler - if (g_gameinfo.game->funcs->pfnModLoad && !g_gameinfo.game->funcs->pfnModLoad((void*)pfnvmMain)) { - LOG(QMM_LOG_ERROR, "QMM") << fmt::format("mod_load(\"{}\"): Mod load failed?\n", mod.path); - goto fail; - } - - // hack in case there isn't a game-specific dllEntry or ModLoad function - if (!g_gameinfo.pfnvmMain) { - g_gameinfo.pfnvmMain = pfnvmMain; - } - - return true; - -fail: - mod_unload(mod); - return false; -} From e12f6958c3a383ceb6bea728699e7f44fed5fbc5 Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 20:53:00 +0200 Subject: [PATCH 09/12] add quick hack for OpenJK. if last segment of qmm_dir is "temp", set it to "base" --- src/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index cc6d10b..5fc1e11 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -520,6 +520,11 @@ static void main_detect_env() { else { g_gameinfo.mod_dir = path_basename(g_gameinfo.qmm_dir); } + + // hack for OpenJK + if (str_striequal(g_gameinfo.mod_dir, "temp")) { + g_gameinfo.mod_dir = "base"; + } } From 88e5bd110722b4ea9e97a4b853ccd673f4442121 Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 20:55:51 +0200 Subject: [PATCH 10/12] consolidate JAMP_vmMain and JAMP_syscall functions into one, and do different things based on which is set of orig_vmMain/orig_export and orig_syscall/orig_import.Print. the previous separated method did not work if QMM was loaded with the new OpenJK API, but the mod was loaded with original/legacy API. also remove G_SV_REGISTER_SHARED_MEMORY, as that is actually the already-existing G_SET_SHARED_BUFFER --- include/game_jamp.h | 5 - src/game_jamp.cpp | 969 +++++++++++++++++++++----------------------- 2 files changed, 460 insertions(+), 514 deletions(-) diff --git a/include/game_jamp.h b/include/game_jamp.h index bd36140..bd97b8f 100644 --- a/include/game_jamp.h +++ b/include/game_jamp.h @@ -12,11 +12,6 @@ Created By: #ifndef QMM2_GAME_JAMP_H #define QMM2_GAME_JAMP_H -// these import messages do not exist in the "legacy" JAMP API but they do in GetModuleAPI -enum { - G_SV_REGISTER_SHARED_MEMORY = 90, // void (char *memory) -}; - // these import messages do not have an exact analogue in JAMP enum { G_ARGS = -100, // char* (void) diff --git a/src/game_jamp.cpp b/src/game_jamp.cpp index 80f1820..15e77af 100644 --- a/src/game_jamp.cpp +++ b/src/game_jamp.cpp @@ -22,20 +22,15 @@ Created By: GEN_QMM_MSGS(JAMP); GEN_EXTS(JAMP); -// store whether or not this mod was loaded as GetGameAPI or not -static bool s_is_GetGameAPI = false; - // do not use macro since this game supports both dllEntry and GetGameAPI entry points static const char* JAMP_eng_msg_names(intptr_t); static const char* JAMP_mod_msg_names(intptr_t); static bool JAMP_autodetect(bool, supportedgame*); -static intptr_t JAMP_syscall_legacy(intptr_t cmd, ...); -static intptr_t JAMP_vmMain_legacy(intptr_t cmd, ...); +static intptr_t JAMP_syscall(intptr_t cmd, ...); +static intptr_t JAMP_vmMain(intptr_t cmd, ...); static void JAMP_dllEntry(eng_syscall); -static intptr_t JAMP_syscall_GGA(intptr_t cmd, ...); -static intptr_t JAMP_vmMain_GGA(intptr_t cmd, ...); static void* JAMP_GetGameAPI(void*, void*); -static bool JAMP_mod_load(void*); +static bool JAMP_mod_load(void*, bool); static void JAMP_mod_unload(); supportedgame_funcs JAMP_funcs = { JAMP_qmm_eng_msgs, @@ -46,7 +41,8 @@ supportedgame_funcs JAMP_funcs = { nullptr, // JAMP_qvmsyscall JAMP_dllEntry, JAMP_GetGameAPI, - JAMP_mod_load, JAMP_mod_unload + JAMP_mod_load, + JAMP_mod_unload, }; @@ -61,123 +57,21 @@ static bool JAMP_autodetect(bool is_GetGameAPI, supportedgame* game) { if (!str_stristr(g_gameinfo.exe_file, "jamp") && !str_stristr(g_gameinfo.exe_file, "openjk.") && !str_stristr(g_gameinfo.exe_file, "openjkded")) return false; - // store how we were loaded - s_is_GetGameAPI = is_GetGameAPI; - return true; } // original syscall pointer that comes from the game engine -static eng_syscall orig_syscall_legacy = nullptr; +static eng_syscall orig_syscall = nullptr; // pointer to vmMain that comes from the mod -static mod_vmMain orig_vmMain_legacy = nullptr; - - -// wrapper syscall function that calls actual engine func in orig_syscall_legacy -// this is how QMM and plugins will call into the engine -static intptr_t JAMP_syscall_legacy(intptr_t cmd, ...) { - QMM_GET_SYSCALL_ARGS(); - -#ifdef _DEBUG - if (cmd != G_PRINT) - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall_legacy({} {}) called\n", JAMP_eng_msg_names(cmd), cmd); -#endif - - if (s_is_GetGameAPI) - return 0; - - intptr_t ret = 0; - - switch (cmd) { - // handle special cmds which QMM uses but JAMP doesn't have an analogue for - case G_ARGS: { - // quake2: char* (*args)(void); - static std::string s; - static char buf[MAX_STRING_CHARS]; - s = ""; - int i = 1; - while (i < orig_syscall_legacy(G_ARGC)) { - orig_syscall_legacy(G_ARGV, buf, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - if (i != 1) - s += " "; - s += buf; - } - ret = (intptr_t)s.c_str(); - break; - } - - default: - // all normal engine functions go to engine - ret = orig_syscall_legacy(cmd, QMM_PUT_SYSCALL_ARGS()); - } - - // do anything that needs to be done after function call here - -#ifdef _DEBUG - if (cmd != G_PRINT) - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall_legacy({} {}) returning {}\n", JAMP_eng_msg_names(cmd), cmd, ret); -#endif - - return ret; -} - - -// wrapper vmMain function that calls actual mod func in orig_vmMain_legacy -// this is how QMM and plugins will call into the mod -static intptr_t JAMP_vmMain_legacy(intptr_t cmd, ...) { - QMM_GET_VMMAIN_ARGS(); - -#ifdef _DEBUG - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain_legacy({} {}) called\n", JAMP_mod_msg_names(cmd), cmd); -#endif - - if (s_is_GetGameAPI) - return 0; - - if (!orig_vmMain_legacy) - return 0; - - // store return value since we do some stuff after the function call is over - intptr_t ret = 0; - - // all normal mod functions go to mod - ret = orig_vmMain_legacy(cmd, QMM_PUT_VMMAIN_ARGS()); - -#ifdef _DEBUG - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain_legacy({} {}) returning {}\n", JAMP_mod_msg_names(cmd), cmd, ret); -#endif +static mod_vmMain orig_vmMain = nullptr; - return ret; -} - - -static void JAMP_dllEntry(eng_syscall syscall) { - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_dllEntry({}) called\n", (void*)syscall); - // store how we were loaded - s_is_GetGameAPI = false; - - // store original syscall from engine - orig_syscall_legacy = syscall; - - // pointer to wrapper vmMain function that calls actual mod vmMain func orig_vmMain - g_gameinfo.pfnvmMain = JAMP_vmMain_legacy; - - // pointer to wrapper syscall function that calls actual engine syscall func - g_gameinfo.pfnsyscall = JAMP_syscall_legacy; - - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_dllEntry({}) returning\n", (void*)syscall); -} - - -// these variables are all for the GGA implementation for OpenJK, but can't add _GGA suffix -// to all because ROUTE_IMPORT/ROUTE_EXPORT macros use these names +// these variables are all for the GGA implementation for OpenJK // a copy of the apiversion int that comes from the game engine -static intptr_t orig_apiversion_GGA = 0; +static intptr_t orig_apiversion = 0; // a copy of the original import struct that comes from the game engine static game_import_t orig_import; @@ -192,7 +86,7 @@ static game_import_t qmm_import = { GEN_IMPORT(Milliseconds, G_MILLISECONDS), GEN_IMPORT(PrecisionTimerStart, G_PRECISIONTIMER_START), GEN_IMPORT(PrecisionTimerEnd, G_PRECISIONTIMER_END), - GEN_IMPORT(SV_RegisterSharedMemory, G_SV_REGISTER_SHARED_MEMORY), + GEN_IMPORT(SV_RegisterSharedMemory, G_SET_SHARED_BUFFER), GEN_IMPORT(RealTime, G_REAL_TIME), GEN_IMPORT(TrueMalloc, G_TRUEMALLOC), GEN_IMPORT(TrueFree, G_TRUEFREE), @@ -543,341 +437,386 @@ static game_export_t qmm_export = { }; -// wrapper syscall function that calls actual engine func from orig_import +// wrapper syscall function that calls actual engine func from orig_import or orig_syscall // this is how QMM and plugins will call into the engine -static intptr_t JAMP_syscall_GGA(intptr_t cmd, ...) { +static intptr_t JAMP_syscall(intptr_t cmd, ...) { QMM_GET_SYSCALL_ARGS(); #ifdef _DEBUG if (cmd != G_PRINT) - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall_GGA({} {}) called\n", JAMP_eng_msg_names(cmd), cmd); + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall({} {}) called\n", JAMP_eng_msg_names(cmd), cmd); #endif - if (!s_is_GetGameAPI) - return 0; - + // store return value since we do some stuff after the function call is over intptr_t ret = 0; - switch (cmd) { - ROUTE_IMPORT(Print, G_PRINT); - ROUTE_IMPORT(Error, G_ERROR); - ROUTE_IMPORT(Milliseconds, G_MILLISECONDS); - ROUTE_IMPORT(PrecisionTimerStart, G_PRECISIONTIMER_START); - ROUTE_IMPORT(PrecisionTimerEnd, G_PRECISIONTIMER_END); - ROUTE_IMPORT(SV_RegisterSharedMemory, G_SV_REGISTER_SHARED_MEMORY); - ROUTE_IMPORT(RealTime, G_REAL_TIME); - ROUTE_IMPORT(TrueMalloc, G_TRUEMALLOC); - ROUTE_IMPORT(TrueFree, G_TRUEFREE); - ROUTE_IMPORT(SnapVector, G_SNAPVECTOR); - ROUTE_IMPORT(Cvar_Register, G_CVAR_REGISTER); - ROUTE_IMPORT(Cvar_Set, G_CVAR_SET); - ROUTE_IMPORT(Cvar_Update, G_CVAR_UPDATE); - ROUTE_IMPORT(Cvar_VariableIntegerValue, G_CVAR_VARIABLE_INTEGER_VALUE); - ROUTE_IMPORT(Cvar_VariableStringBuffer, G_CVAR_VARIABLE_STRING_BUFFER); - ROUTE_IMPORT(Argc, G_ARGC); - ROUTE_IMPORT(Argv, G_ARGV); - ROUTE_IMPORT(FS_Close, G_FS_FCLOSE_FILE); - ROUTE_IMPORT(FS_GetFileList, G_FS_GETFILELIST); - ROUTE_IMPORT(FS_Open, G_FS_FOPEN_FILE); - ROUTE_IMPORT(FS_Read, G_FS_READ); - ROUTE_IMPORT(FS_Write, G_FS_WRITE); - ROUTE_IMPORT(AdjustAreaPortalState, G_ADJUST_AREA_PORTAL_STATE); - ROUTE_IMPORT(AreasConnected, G_AREAS_CONNECTED); - ROUTE_IMPORT(DebugPolygonCreate, G_DEBUG_POLYGON_CREATE); - ROUTE_IMPORT(DebugPolygonDelete, G_DEBUG_POLYGON_DELETE); - ROUTE_IMPORT(DropClient, G_DROP_CLIENT); - ROUTE_IMPORT(EntitiesInBox, G_ENTITIES_IN_BOX); - ROUTE_IMPORT(EntityContact, G_ENTITY_CONTACT); - ROUTE_IMPORT(GetConfigstring, G_GET_CONFIGSTRING); - ROUTE_IMPORT(GetEntityToken, G_GET_ENTITY_TOKEN); - ROUTE_IMPORT(GetServerinfo, G_GET_SERVERINFO); - ROUTE_IMPORT(GetUsercmd, G_GET_USERCMD); - ROUTE_IMPORT(GetUserinfo, G_GET_USERINFO); - ROUTE_IMPORT(InPVS, G_IN_PVS); - ROUTE_IMPORT(InPVSIgnorePortals, G_IN_PVS_IGNORE_PORTALS); - ROUTE_IMPORT(LinkEntity, G_LINKENTITY); - ROUTE_IMPORT(LocateGameData, G_LOCATE_GAME_DATA); - ROUTE_IMPORT(PointContents, G_POINT_CONTENTS); - ROUTE_IMPORT(SendConsoleCommand, G_SEND_CONSOLE_COMMAND); - ROUTE_IMPORT(SendServerCommand, G_SEND_SERVER_COMMAND); - ROUTE_IMPORT(SetBrushModel, G_SET_BRUSH_MODEL); - ROUTE_IMPORT(SetConfigstring, G_SET_CONFIGSTRING); - ROUTE_IMPORT(SetServerCull, G_SET_SERVER_CULL); - ROUTE_IMPORT(SetUserinfo, G_SET_USERINFO); - ROUTE_IMPORT(SiegePersSet, G_SIEGEPERSSET); - ROUTE_IMPORT(SiegePersGet, G_SIEGEPERSGET); - ROUTE_IMPORT(Trace, G_TRACE); - ROUTE_IMPORT(UnlinkEntity, G_UNLINKENTITY); - ROUTE_IMPORT(ROFF_Clean, G_ROFF_CLEAN); - ROUTE_IMPORT(ROFF_UpdateEntities, G_ROFF_UPDATE_ENTITIES); - ROUTE_IMPORT(ROFF_Cache, G_ROFF_CACHE); - ROUTE_IMPORT(ROFF_Play, G_ROFF_PLAY); - ROUTE_IMPORT(ROFF_Purge_Ent, G_ROFF_PURGE_ENT); - ROUTE_IMPORT(ICARUS_RunScript, G_ICARUS_RUNSCRIPT); - ROUTE_IMPORT(ICARUS_RegisterScript, G_ICARUS_REGISTERSCRIPT); - ROUTE_IMPORT(ICARUS_Init, G_ICARUS_INIT); - ROUTE_IMPORT(ICARUS_ValidEnt, G_ICARUS_VALIDENT); - ROUTE_IMPORT(ICARUS_IsInitialized, G_ICARUS_ISINITIALIZED); - ROUTE_IMPORT(ICARUS_MaintainTaskManager, G_ICARUS_MAINTAINTASKMANAGER); - ROUTE_IMPORT(ICARUS_IsRunning, G_ICARUS_ISRUNNING); - ROUTE_IMPORT(ICARUS_TaskIDPending, G_ICARUS_TASKIDPENDING); - ROUTE_IMPORT(ICARUS_InitEnt, G_ICARUS_INITENT); - ROUTE_IMPORT(ICARUS_FreeEnt, G_ICARUS_FREEENT); - ROUTE_IMPORT(ICARUS_AssociateEnt, G_ICARUS_ASSOCIATEENT); - ROUTE_IMPORT(ICARUS_Shutdown, G_ICARUS_SHUTDOWN); - ROUTE_IMPORT(ICARUS_TaskIDSet, G_ICARUS_TASKIDSET); - ROUTE_IMPORT(ICARUS_TaskIDComplete, G_ICARUS_TASKIDCOMPLETE); - ROUTE_IMPORT(ICARUS_SetVar, G_ICARUS_SETVAR); - ROUTE_IMPORT(ICARUS_VariableDeclared, G_ICARUS_VARIABLEDECLARED); - ROUTE_IMPORT(ICARUS_GetFloatVariable, G_ICARUS_GETFLOATVARIABLE); - ROUTE_IMPORT(ICARUS_GetStringVariable, G_ICARUS_GETSTRINGVARIABLE); - ROUTE_IMPORT(ICARUS_GetVectorVariable, G_ICARUS_GETVECTORVARIABLE); - ROUTE_IMPORT(Nav_Init, G_NAV_INIT); - ROUTE_IMPORT(Nav_Free, G_NAV_FREE); - ROUTE_IMPORT(Nav_Load, G_NAV_LOAD); - ROUTE_IMPORT(Nav_Save, G_NAV_SAVE); - ROUTE_IMPORT(Nav_AddRawPoint, G_NAV_ADDRAWPOINT); - ROUTE_IMPORT(Nav_CalculatePaths, G_NAV_CALCULATEPATHS); - ROUTE_IMPORT(Nav_HardConnect, G_NAV_HARDCONNECT); - ROUTE_IMPORT(Nav_ShowNodes, G_NAV_SHOWNODES); - ROUTE_IMPORT(Nav_ShowEdges, G_NAV_SHOWEDGES); - ROUTE_IMPORT(Nav_ShowPath, G_NAV_SHOWPATH); - ROUTE_IMPORT(Nav_GetNearestNode, G_NAV_GETNEARESTNODE); - ROUTE_IMPORT(Nav_GetBestNode, G_NAV_GETBESTNODE); - ROUTE_IMPORT(Nav_GetNodePosition, G_NAV_GETNODEPOSITION); - ROUTE_IMPORT(Nav_GetNodeNumEdges, G_NAV_GETNODENUMEDGES); - ROUTE_IMPORT(Nav_GetNodeEdge, G_NAV_GETNODEEDGE); - ROUTE_IMPORT(Nav_GetNumNodes, G_NAV_GETNUMNODES); - ROUTE_IMPORT(Nav_Connected, G_NAV_CONNECTED); - ROUTE_IMPORT(Nav_GetPathCost, G_NAV_GETPATHCOST); - ROUTE_IMPORT(Nav_GetEdgeCost, G_NAV_GETEDGECOST); - ROUTE_IMPORT(Nav_GetProjectedNode, G_NAV_GETPROJECTEDNODE); - ROUTE_IMPORT(Nav_CheckFailedNodes, G_NAV_CHECKFAILEDNODES); - ROUTE_IMPORT(Nav_AddFailedNode, G_NAV_ADDFAILEDNODE); - ROUTE_IMPORT(Nav_NodeFailed, G_NAV_NODEFAILED); - ROUTE_IMPORT(Nav_NodesAreNeighbors, G_NAV_NODESARENEIGHBORS); - ROUTE_IMPORT(Nav_ClearFailedEdge, G_NAV_CLEARFAILEDEDGE); - ROUTE_IMPORT(Nav_ClearAllFailedEdges, G_NAV_CLEARALLFAILEDEDGES); - ROUTE_IMPORT(Nav_EdgeFailed, G_NAV_EDGEFAILED); - ROUTE_IMPORT(Nav_AddFailedEdge, G_NAV_ADDFAILEDEDGE); - ROUTE_IMPORT(Nav_CheckFailedEdge, G_NAV_CHECKFAILEDEDGE); - ROUTE_IMPORT(Nav_CheckAllFailedEdges, G_NAV_CHECKALLFAILEDEDGES); - ROUTE_IMPORT(Nav_RouteBlocked, G_NAV_ROUTEBLOCKED); - ROUTE_IMPORT(Nav_GetBestNodeAltRoute, G_NAV_GETBESTNODEALTROUTE); - ROUTE_IMPORT(Nav_GetBestNodeAltRoute2, G_NAV_GETBESTNODEALT2); - ROUTE_IMPORT(Nav_GetBestPathBetweenEnts, G_NAV_GETBESTPATHBETWEENENTS); - ROUTE_IMPORT(Nav_GetNodeRadius, G_NAV_GETNODERADIUS); - ROUTE_IMPORT(Nav_CheckBlockedEdges, G_NAV_CHECKBLOCKEDEDGES); - ROUTE_IMPORT(Nav_ClearCheckedNodes, G_NAV_CLEARCHECKEDNODES); - ROUTE_IMPORT(Nav_CheckedNode, G_NAV_CHECKEDNODE); - ROUTE_IMPORT(Nav_SetCheckedNode, G_NAV_SETCHECKEDNODE); - ROUTE_IMPORT(Nav_FlagAllNodes, G_NAV_FLAGALLNODES); - ROUTE_IMPORT(Nav_GetPathsCalculated, G_NAV_GETPATHSCALCULATED); - ROUTE_IMPORT(Nav_SetPathsCalculated, G_NAV_SETPATHSCALCULATED); - ROUTE_IMPORT(BotAllocateClient, G_BOT_ALLOCATE_CLIENT); - ROUTE_IMPORT(BotFreeClient, G_BOT_FREE_CLIENT); - ROUTE_IMPORT(BotLoadCharacter, BOTLIB_AI_LOAD_CHARACTER); - ROUTE_IMPORT(BotFreeCharacter, BOTLIB_AI_FREE_CHARACTER); - ROUTE_IMPORT(Characteristic_Float, BOTLIB_AI_CHARACTERISTIC_FLOAT); - ROUTE_IMPORT(Characteristic_BFloat, BOTLIB_AI_CHARACTERISTIC_BFLOAT); - ROUTE_IMPORT(Characteristic_Integer, BOTLIB_AI_CHARACTERISTIC_INTEGER); - ROUTE_IMPORT(Characteristic_BInteger, BOTLIB_AI_CHARACTERISTIC_BINTEGER); - ROUTE_IMPORT(Characteristic_String, BOTLIB_AI_CHARACTERISTIC_STRING); - ROUTE_IMPORT(BotAllocChatState, BOTLIB_AI_ALLOC_CHAT_STATE); - ROUTE_IMPORT(BotFreeChatState, BOTLIB_AI_FREE_CHAT_STATE); - ROUTE_IMPORT(BotQueueConsoleMessage, BOTLIB_AI_QUEUE_CONSOLE_MESSAGE); - ROUTE_IMPORT(BotRemoveConsoleMessage, BOTLIB_AI_REMOVE_CONSOLE_MESSAGE); - ROUTE_IMPORT(BotNextConsoleMessage, BOTLIB_AI_NEXT_CONSOLE_MESSAGE); - ROUTE_IMPORT(BotNumConsoleMessages, BOTLIB_AI_NUM_CONSOLE_MESSAGE); - ROUTE_IMPORT(BotInitialChat, BOTLIB_AI_INITIAL_CHAT); - ROUTE_IMPORT(BotReplyChat, BOTLIB_AI_REPLY_CHAT); - ROUTE_IMPORT(BotChatLength, BOTLIB_AI_CHAT_LENGTH); - ROUTE_IMPORT(BotEnterChat, BOTLIB_AI_ENTER_CHAT); - ROUTE_IMPORT(StringContains, BOTLIB_AI_STRING_CONTAINS); - ROUTE_IMPORT(BotFindMatch, BOTLIB_AI_FIND_MATCH); - ROUTE_IMPORT(BotMatchVariable, BOTLIB_AI_MATCH_VARIABLE); - ROUTE_IMPORT(UnifyWhiteSpaces, BOTLIB_AI_UNIFY_WHITE_SPACES); - ROUTE_IMPORT(BotReplaceSynonyms, BOTLIB_AI_REPLACE_SYNONYMS); - ROUTE_IMPORT(BotLoadChatFile, BOTLIB_AI_LOAD_CHAT_FILE); - ROUTE_IMPORT(BotSetChatGender, BOTLIB_AI_SET_CHAT_GENDER); - ROUTE_IMPORT(BotSetChatName, BOTLIB_AI_SET_CHAT_NAME); - ROUTE_IMPORT(BotResetGoalState, BOTLIB_AI_RESET_GOAL_STATE); - ROUTE_IMPORT(BotResetAvoidGoals, BOTLIB_AI_RESET_AVOID_GOALS); - ROUTE_IMPORT(BotPushGoal, BOTLIB_AI_PUSH_GOAL); - ROUTE_IMPORT(BotPopGoal, BOTLIB_AI_POP_GOAL); - ROUTE_IMPORT(BotEmptyGoalStack, BOTLIB_AI_EMPTY_GOAL_STACK); - ROUTE_IMPORT(BotDumpAvoidGoals, BOTLIB_AI_DUMP_AVOID_GOALS); - ROUTE_IMPORT(BotDumpGoalStack, BOTLIB_AI_DUMP_GOAL_STACK); - ROUTE_IMPORT(BotGoalName, BOTLIB_AI_GOAL_NAME); - ROUTE_IMPORT(BotGetTopGoal, BOTLIB_AI_GET_TOP_GOAL); - ROUTE_IMPORT(BotGetSecondGoal, BOTLIB_AI_GET_SECOND_GOAL); - ROUTE_IMPORT(BotChooseLTGItem, BOTLIB_AI_CHOOSE_LTG_ITEM); - ROUTE_IMPORT(BotChooseNBGItem, BOTLIB_AI_CHOOSE_NBG_ITEM); - ROUTE_IMPORT(BotTouchingGoal, BOTLIB_AI_TOUCHING_GOAL); - ROUTE_IMPORT(BotItemGoalInVisButNotVisible, BOTLIB_AI_ITEM_GOAL_IN_VIS_BUT_NOT_VISIBLE); - ROUTE_IMPORT(BotGetLevelItemGoal, BOTLIB_AI_GET_LEVEL_ITEM_GOAL); - ROUTE_IMPORT(BotAvoidGoalTime, BOTLIB_AI_AVOID_GOAL_TIME); - ROUTE_IMPORT(BotInitLevelItems, BOTLIB_AI_INIT_LEVEL_ITEMS); - ROUTE_IMPORT(BotUpdateEntityItems, BOTLIB_AI_UPDATE_ENTITY_ITEMS); - ROUTE_IMPORT(BotLoadItemWeights, BOTLIB_AI_LOAD_ITEM_WEIGHTS); - ROUTE_IMPORT(BotFreeItemWeights, BOTLIB_AI_FREE_ITEM_WEIGHTS); - ROUTE_IMPORT(BotSaveGoalFuzzyLogic, BOTLIB_AI_SAVE_GOAL_FUZZY_LOGIC); - ROUTE_IMPORT(BotAllocGoalState, BOTLIB_AI_ALLOC_GOAL_STATE); - ROUTE_IMPORT(BotFreeGoalState, BOTLIB_AI_FREE_GOAL_STATE); - ROUTE_IMPORT(BotResetMoveState, BOTLIB_AI_RESET_MOVE_STATE); - ROUTE_IMPORT(BotMoveToGoal, BOTLIB_AI_MOVE_TO_GOAL); - ROUTE_IMPORT(BotMoveInDirection, BOTLIB_AI_MOVE_IN_DIRECTION); - ROUTE_IMPORT(BotResetAvoidReach, BOTLIB_AI_RESET_AVOID_REACH); - ROUTE_IMPORT(BotResetLastAvoidReach, BOTLIB_AI_RESET_LAST_AVOID_REACH); - ROUTE_IMPORT(BotReachabilityArea, BOTLIB_AI_REACHABILITY_AREA); - ROUTE_IMPORT(BotMovementViewTarget, BOTLIB_AI_MOVEMENT_VIEW_TARGET); - ROUTE_IMPORT(BotAllocMoveState, BOTLIB_AI_ALLOC_MOVE_STATE); - ROUTE_IMPORT(BotFreeMoveState, BOTLIB_AI_FREE_MOVE_STATE); - ROUTE_IMPORT(BotInitMoveState, BOTLIB_AI_INIT_MOVE_STATE); - ROUTE_IMPORT(BotChooseBestFightWeapon, BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON); - ROUTE_IMPORT(BotGetWeaponInfo, BOTLIB_AI_GET_WEAPON_INFO); - ROUTE_IMPORT(BotLoadWeaponWeights, BOTLIB_AI_LOAD_WEAPON_WEIGHTS); - ROUTE_IMPORT(BotAllocWeaponState, BOTLIB_AI_ALLOC_WEAPON_STATE); - ROUTE_IMPORT(BotFreeWeaponState, BOTLIB_AI_FREE_WEAPON_STATE); - ROUTE_IMPORT(BotResetWeaponState, BOTLIB_AI_RESET_WEAPON_STATE); - ROUTE_IMPORT(GeneticParentsAndChildSelection, BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION); - ROUTE_IMPORT(BotInterbreedGoalFuzzyLogic, BOTLIB_AI_INTERBREED_GOAL_FUZZY_LOGIC); - ROUTE_IMPORT(BotMutateGoalFuzzyLogic, BOTLIB_AI_MUTATE_GOAL_FUZZY_LOGIC); - ROUTE_IMPORT(BotGetNextCampSpotGoal, BOTLIB_AI_GET_NEXT_CAMP_SPOT_GOAL); - ROUTE_IMPORT(BotGetMapLocationGoal, BOTLIB_AI_GET_MAP_LOCATION_GOAL); - ROUTE_IMPORT(BotNumInitialChats, BOTLIB_AI_NUM_INITIAL_CHATS); - ROUTE_IMPORT(BotGetChatMessage, BOTLIB_AI_GET_CHAT_MESSAGE); - ROUTE_IMPORT(BotRemoveFromAvoidGoals, BOTLIB_AI_REMOVE_FROM_AVOID_GOALS); - ROUTE_IMPORT(BotPredictVisiblePosition, BOTLIB_AI_PREDICT_VISIBLE_POSITION); - ROUTE_IMPORT(BotSetAvoidGoalTime, BOTLIB_AI_SET_AVOID_GOAL_TIME); - ROUTE_IMPORT(BotAddAvoidSpot, BOTLIB_AI_ADD_AVOID_SPOT); - ROUTE_IMPORT(BotLibSetup, BOTLIB_SETUP); - ROUTE_IMPORT(BotLibShutdown, BOTLIB_SHUTDOWN); - ROUTE_IMPORT(BotLibVarSet, BOTLIB_LIBVAR_SET); - ROUTE_IMPORT(BotLibVarGet, BOTLIB_LIBVAR_GET); - ROUTE_IMPORT(BotLibDefine, BOTLIB_PC_ADD_GLOBAL_DEFINE); - ROUTE_IMPORT(BotLibStartFrame, BOTLIB_START_FRAME); - ROUTE_IMPORT(BotLibLoadMap, BOTLIB_LOAD_MAP); - ROUTE_IMPORT(BotLibUpdateEntity, BOTLIB_UPDATENTITY); - ROUTE_IMPORT(BotLibTest, BOTLIB_TEST); - ROUTE_IMPORT(BotGetSnapshotEntity, BOTLIB_GET_SNAPSHOT_ENTITY); - ROUTE_IMPORT(BotGetServerCommand, BOTLIB_GET_CONSOLE_MESSAGE); - ROUTE_IMPORT(BotUserCommand, BOTLIB_USER_COMMAND); - ROUTE_IMPORT(BotUpdateWaypoints, G_BOT_UPDATEWAYPOINTS); - ROUTE_IMPORT(BotCalculatePaths, G_BOT_CALCULATEPATHS); - ROUTE_IMPORT(AAS_EnableRoutingArea, BOTLIB_AAS_ENABLE_ROUTING_AREA); - ROUTE_IMPORT(AAS_BBoxAreas, BOTLIB_AAS_BBOX_AREAS); - ROUTE_IMPORT(AAS_AreaInfo, BOTLIB_AAS_AREA_INFO); - ROUTE_IMPORT(AAS_EntityInfo, BOTLIB_AAS_ENTITY_INFO); - ROUTE_IMPORT(AAS_Initialized, BOTLIB_AAS_INITIALIZED); - ROUTE_IMPORT(AAS_PresenceTypeBoundingBox, BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX); - ROUTE_IMPORT(AAS_Time, BOTLIB_AAS_TIME); - ROUTE_IMPORT(AAS_PointAreaNum, BOTLIB_AAS_POINT_AREA_NUM); - ROUTE_IMPORT(AAS_TraceAreas, BOTLIB_AAS_TRACE_AREAS); - ROUTE_IMPORT(AAS_PointContents, BOTLIB_AAS_POINT_CONTENTS); - ROUTE_IMPORT(AAS_NextBSPEntity, BOTLIB_AAS_NEXT_BSP_ENTITY); - ROUTE_IMPORT(AAS_ValueForBSPEpairKey, BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY); - ROUTE_IMPORT(AAS_VectorForBSPEpairKey, BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY); - ROUTE_IMPORT(AAS_FloatForBSPEpairKey, BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY); - ROUTE_IMPORT(AAS_IntForBSPEpairKey, BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY); - ROUTE_IMPORT(AAS_AreaReachability, BOTLIB_AAS_AREA_REACHABILITY); - ROUTE_IMPORT(AAS_AreaTravelTimeToGoalArea, BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA); - ROUTE_IMPORT(AAS_Swimming, BOTLIB_AAS_SWIMMING); - ROUTE_IMPORT(AAS_PredictClientMovement, BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT); - ROUTE_IMPORT(AAS_AlternativeRouteGoals, BOTLIB_AAS_ALTERNATIVE_ROUTE_GOAL); - ROUTE_IMPORT(AAS_PredictRoute, BOTLIB_AAS_PREDICT_ROUTE); - ROUTE_IMPORT(AAS_PointReachabilityAreaIndex, BOTLIB_AAS_POINT_REACHABILITY_AREA_INDEX); - ROUTE_IMPORT(EA_Say, BOTLIB_EA_SAY); - ROUTE_IMPORT(EA_SayTeam, BOTLIB_EA_SAY_TEAM); - ROUTE_IMPORT(EA_Command, BOTLIB_EA_COMMAND); - ROUTE_IMPORT(EA_Action, BOTLIB_EA_ACTION); - ROUTE_IMPORT(EA_Gesture, BOTLIB_EA_GESTURE); - ROUTE_IMPORT(EA_Talk, BOTLIB_EA_TALK); - ROUTE_IMPORT(EA_Attack, BOTLIB_EA_ATTACK); - ROUTE_IMPORT(EA_Alt_Attack, BOTLIB_EA_ALT_ATTACK); - ROUTE_IMPORT(EA_ForcePower, BOTLIB_EA_FORCEPOWER); - ROUTE_IMPORT(EA_Use, BOTLIB_EA_USE); - ROUTE_IMPORT(EA_Respawn, BOTLIB_EA_RESPAWN); - ROUTE_IMPORT(EA_Crouch, BOTLIB_EA_CROUCH); - ROUTE_IMPORT(EA_MoveUp, BOTLIB_EA_MOVE_UP); - ROUTE_IMPORT(EA_MoveDown, BOTLIB_EA_MOVE_DOWN); - ROUTE_IMPORT(EA_MoveForward, BOTLIB_EA_MOVE_FORWARD); - ROUTE_IMPORT(EA_MoveBack, BOTLIB_EA_MOVE_BACK); - ROUTE_IMPORT(EA_MoveLeft, BOTLIB_EA_MOVE_LEFT); - ROUTE_IMPORT(EA_MoveRight, BOTLIB_EA_MOVE_RIGHT); - ROUTE_IMPORT(EA_SelectWeapon, BOTLIB_EA_SELECT_WEAPON); - ROUTE_IMPORT(EA_Jump, BOTLIB_EA_JUMP); - ROUTE_IMPORT(EA_DelayedJump, BOTLIB_EA_DELAYED_JUMP); - ROUTE_IMPORT(EA_Move, BOTLIB_EA_MOVE); - ROUTE_IMPORT(EA_View, BOTLIB_EA_VIEW); - ROUTE_IMPORT(EA_EndRegular, BOTLIB_EA_END_REGULAR); - ROUTE_IMPORT(EA_GetInput, BOTLIB_EA_GET_INPUT); - ROUTE_IMPORT(EA_ResetInput, BOTLIB_EA_RESET_INPUT); - ROUTE_IMPORT(PC_LoadSource, BOTLIB_PC_LOAD_SOURCE); - ROUTE_IMPORT(PC_FreeSource, BOTLIB_PC_FREE_SOURCE); - ROUTE_IMPORT(PC_ReadToken, BOTLIB_PC_READ_TOKEN); - ROUTE_IMPORT(PC_SourceFileAndLine, BOTLIB_PC_SOURCE_FILE_AND_LINE); - ROUTE_IMPORT(R_RegisterSkin, G_R_REGISTERSKIN); - ROUTE_IMPORT(SetActiveSubBSP, G_SET_ACTIVE_SUBBSP); - ROUTE_IMPORT(CM_RegisterTerrain, G_CM_REGISTER_TERRAIN); - ROUTE_IMPORT(RMG_Init, G_RMG_INIT); - ROUTE_IMPORT(G2API_ListModelBones, G_G2_LISTBONES); - ROUTE_IMPORT(G2API_ListModelSurfaces, G_G2_LISTSURFACES); - ROUTE_IMPORT(G2API_HaveWeGhoul2Models, G_G2_HAVEWEGHOULMODELS); - ROUTE_IMPORT(G2API_SetGhoul2ModelIndexes, G_G2_SETMODELS); - ROUTE_IMPORT(G2API_GetBoltMatrix, G_G2_GETBOLT); - ROUTE_IMPORT(G2API_GetBoltMatrix_NoReconstruct, G_G2_GETBOLT_NOREC); - ROUTE_IMPORT(G2API_GetBoltMatrix_NoRecNoRot, G_G2_GETBOLT_NOREC_NOROT); - ROUTE_IMPORT(G2API_InitGhoul2Model, G_G2_INITGHOUL2MODEL); - ROUTE_IMPORT(G2API_SetSkin, G_G2_SETSKIN); - ROUTE_IMPORT(G2API_Ghoul2Size, G_G2_SIZE); - ROUTE_IMPORT(G2API_AddBolt, G_G2_ADDBOLT); - ROUTE_IMPORT(G2API_SetBoltInfo, G_G2_SETBOLTINFO); - ROUTE_IMPORT(G2API_SetBoneAngles, G_G2_ANGLEOVERRIDE); - ROUTE_IMPORT(G2API_SetBoneAnim, G_G2_PLAYANIM); - ROUTE_IMPORT(G2API_GetBoneAnim, G_G2_GETBONEANIM); - ROUTE_IMPORT(G2API_GetGLAName, G_G2_GETGLANAME); - ROUTE_IMPORT(G2API_CopyGhoul2Instance, G_G2_COPYGHOUL2INSTANCE); - ROUTE_IMPORT(G2API_CopySpecificGhoul2Model, G_G2_COPYSPECIFICGHOUL2MODEL); - ROUTE_IMPORT(G2API_DuplicateGhoul2Instance, G_G2_DUPLICATEGHOUL2INSTANCE); - ROUTE_IMPORT(G2API_HasGhoul2ModelOnIndex, G_G2_HASGHOUL2MODELONINDEX); - ROUTE_IMPORT(G2API_RemoveGhoul2Model, G_G2_REMOVEGHOUL2MODEL); - ROUTE_IMPORT(G2API_RemoveGhoul2Models, G_G2_REMOVEGHOUL2MODELS); - ROUTE_IMPORT(G2API_CleanGhoul2Models, G_G2_CLEANMODELS); - ROUTE_IMPORT(G2API_CollisionDetect, G_G2_COLLISIONDETECT); - ROUTE_IMPORT(G2API_CollisionDetectCache, G_G2_COLLISIONDETECTCACHE); - ROUTE_IMPORT(G2API_SetRootSurface, G_G2_SETROOTSURFACE); - ROUTE_IMPORT(G2API_SetSurfaceOnOff, G_G2_SETSURFACEONOFF); - ROUTE_IMPORT(G2API_SetNewOrigin, G_G2_SETNEWORIGIN); - ROUTE_IMPORT(G2API_DoesBoneExist, G_G2_DOESBONEEXIST); - ROUTE_IMPORT(G2API_GetSurfaceRenderStatus, G_G2_GETSURFACERENDERSTATUS); - ROUTE_IMPORT(G2API_AbsurdSmoothing, G_G2_ABSURDSMOOTHING); - ROUTE_IMPORT(G2API_SetRagDoll, G_G2_SETRAGDOLL); - ROUTE_IMPORT(G2API_AnimateG2Models, G_G2_ANIMATEG2MODELS); - ROUTE_IMPORT(G2API_RagPCJConstraint, G_G2_RAGPCJCONSTRAINT); - ROUTE_IMPORT(G2API_RagPCJGradientSpeed, G_G2_RAGPCJGRADIENTSPEED); - ROUTE_IMPORT(G2API_RagEffectorGoal, G_G2_RAGEFFECTORGOAL); - ROUTE_IMPORT(G2API_GetRagBonePos, G_G2_GETRAGBONEPOS); - ROUTE_IMPORT(G2API_RagEffectorKick, G_G2_RAGEFFECTORKICK); - ROUTE_IMPORT(G2API_RagForceSolve, G_G2_RAGFORCESOLVE); - ROUTE_IMPORT(G2API_SetBoneIKState, G_G2_SETBONEIKSTATE); - ROUTE_IMPORT(G2API_IKMove, G_G2_IKMOVE); - ROUTE_IMPORT(G2API_RemoveBone, G_G2_REMOVEBONE); - ROUTE_IMPORT(G2API_AttachInstanceToEntNum, G_G2_ATTACHINSTANCETOENTNUM); - ROUTE_IMPORT(G2API_ClearAttachedInstance, G_G2_CLEARATTACHEDINSTANCE); - ROUTE_IMPORT(G2API_CleanEntAttachments, G_G2_CLEANENTATTACHMENTS); - ROUTE_IMPORT(G2API_OverrideServer, G_G2_OVERRIDESERVER); - ROUTE_IMPORT(G2API_GetSurfaceName, G_G2_GETSURFACENAME); + // if QMM was loaded with the official JAMP or OpenJK "legacy" API (which shouldn't happen, but whatever) + if (orig_syscall) { + switch (cmd) { + // handle special cmds which QMM uses but JAMP doesn't have an analogue for + case G_ARGS: { + // quake2: char* (*args)(void); + static std::string s; + static char buf[MAX_STRING_CHARS]; + s = ""; + int i = 1; + while (i < orig_syscall(G_ARGC)) { + orig_syscall(G_ARGV, i, buf, sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + if (i != 1) + s += " "; + s += buf; + } + ret = (intptr_t)s.c_str(); + break; + } - default: - break; - }; + default: + // all normal engine functions go to engine + ret = orig_syscall(cmd, QMM_PUT_SYSCALL_ARGS()); + } + } + // if QMM was loaded with the OpenJK "new" API + else if (orig_import.Print) { + switch (cmd) { + ROUTE_IMPORT(Print, G_PRINT); + ROUTE_IMPORT(Error, G_ERROR); + ROUTE_IMPORT(Milliseconds, G_MILLISECONDS); + ROUTE_IMPORT(PrecisionTimerStart, G_PRECISIONTIMER_START); + ROUTE_IMPORT(PrecisionTimerEnd, G_PRECISIONTIMER_END); + ROUTE_IMPORT(SV_RegisterSharedMemory, G_SET_SHARED_BUFFER); + ROUTE_IMPORT(RealTime, G_REAL_TIME); + ROUTE_IMPORT(TrueMalloc, G_TRUEMALLOC); + ROUTE_IMPORT(TrueFree, G_TRUEFREE); + ROUTE_IMPORT(SnapVector, G_SNAPVECTOR); + ROUTE_IMPORT(Cvar_Register, G_CVAR_REGISTER); + ROUTE_IMPORT(Cvar_Set, G_CVAR_SET); + ROUTE_IMPORT(Cvar_Update, G_CVAR_UPDATE); + ROUTE_IMPORT(Cvar_VariableIntegerValue, G_CVAR_VARIABLE_INTEGER_VALUE); + ROUTE_IMPORT(Cvar_VariableStringBuffer, G_CVAR_VARIABLE_STRING_BUFFER); + ROUTE_IMPORT(Argc, G_ARGC); + ROUTE_IMPORT(Argv, G_ARGV); + ROUTE_IMPORT(FS_Close, G_FS_FCLOSE_FILE); + ROUTE_IMPORT(FS_GetFileList, G_FS_GETFILELIST); + ROUTE_IMPORT(FS_Open, G_FS_FOPEN_FILE); + ROUTE_IMPORT(FS_Read, G_FS_READ); + ROUTE_IMPORT(FS_Write, G_FS_WRITE); + ROUTE_IMPORT(AdjustAreaPortalState, G_ADJUST_AREA_PORTAL_STATE); + ROUTE_IMPORT(AreasConnected, G_AREAS_CONNECTED); + ROUTE_IMPORT(DebugPolygonCreate, G_DEBUG_POLYGON_CREATE); + ROUTE_IMPORT(DebugPolygonDelete, G_DEBUG_POLYGON_DELETE); + ROUTE_IMPORT(DropClient, G_DROP_CLIENT); + ROUTE_IMPORT(EntitiesInBox, G_ENTITIES_IN_BOX); + ROUTE_IMPORT(EntityContact, G_ENTITY_CONTACT); + ROUTE_IMPORT(GetConfigstring, G_GET_CONFIGSTRING); + ROUTE_IMPORT(GetEntityToken, G_GET_ENTITY_TOKEN); + ROUTE_IMPORT(GetServerinfo, G_GET_SERVERINFO); + ROUTE_IMPORT(GetUsercmd, G_GET_USERCMD); + ROUTE_IMPORT(GetUserinfo, G_GET_USERINFO); + ROUTE_IMPORT(InPVS, G_IN_PVS); + ROUTE_IMPORT(InPVSIgnorePortals, G_IN_PVS_IGNORE_PORTALS); + ROUTE_IMPORT(LinkEntity, G_LINKENTITY); + ROUTE_IMPORT(LocateGameData, G_LOCATE_GAME_DATA); + ROUTE_IMPORT(PointContents, G_POINT_CONTENTS); + ROUTE_IMPORT(SendConsoleCommand, G_SEND_CONSOLE_COMMAND); + ROUTE_IMPORT(SendServerCommand, G_SEND_SERVER_COMMAND); + ROUTE_IMPORT(SetBrushModel, G_SET_BRUSH_MODEL); + ROUTE_IMPORT(SetConfigstring, G_SET_CONFIGSTRING); + ROUTE_IMPORT(SetServerCull, G_SET_SERVER_CULL); + ROUTE_IMPORT(SetUserinfo, G_SET_USERINFO); + ROUTE_IMPORT(SiegePersSet, G_SIEGEPERSSET); + ROUTE_IMPORT(SiegePersGet, G_SIEGEPERSGET); + ROUTE_IMPORT(Trace, G_TRACE); + ROUTE_IMPORT(UnlinkEntity, G_UNLINKENTITY); + ROUTE_IMPORT(ROFF_Clean, G_ROFF_CLEAN); + ROUTE_IMPORT(ROFF_UpdateEntities, G_ROFF_UPDATE_ENTITIES); + ROUTE_IMPORT(ROFF_Cache, G_ROFF_CACHE); + ROUTE_IMPORT(ROFF_Play, G_ROFF_PLAY); + ROUTE_IMPORT(ROFF_Purge_Ent, G_ROFF_PURGE_ENT); + ROUTE_IMPORT(ICARUS_RunScript, G_ICARUS_RUNSCRIPT); + ROUTE_IMPORT(ICARUS_RegisterScript, G_ICARUS_REGISTERSCRIPT); + ROUTE_IMPORT(ICARUS_Init, G_ICARUS_INIT); + ROUTE_IMPORT(ICARUS_ValidEnt, G_ICARUS_VALIDENT); + ROUTE_IMPORT(ICARUS_IsInitialized, G_ICARUS_ISINITIALIZED); + ROUTE_IMPORT(ICARUS_MaintainTaskManager, G_ICARUS_MAINTAINTASKMANAGER); + ROUTE_IMPORT(ICARUS_IsRunning, G_ICARUS_ISRUNNING); + ROUTE_IMPORT(ICARUS_TaskIDPending, G_ICARUS_TASKIDPENDING); + ROUTE_IMPORT(ICARUS_InitEnt, G_ICARUS_INITENT); + ROUTE_IMPORT(ICARUS_FreeEnt, G_ICARUS_FREEENT); + ROUTE_IMPORT(ICARUS_AssociateEnt, G_ICARUS_ASSOCIATEENT); + ROUTE_IMPORT(ICARUS_Shutdown, G_ICARUS_SHUTDOWN); + ROUTE_IMPORT(ICARUS_TaskIDSet, G_ICARUS_TASKIDSET); + ROUTE_IMPORT(ICARUS_TaskIDComplete, G_ICARUS_TASKIDCOMPLETE); + ROUTE_IMPORT(ICARUS_SetVar, G_ICARUS_SETVAR); + ROUTE_IMPORT(ICARUS_VariableDeclared, G_ICARUS_VARIABLEDECLARED); + ROUTE_IMPORT(ICARUS_GetFloatVariable, G_ICARUS_GETFLOATVARIABLE); + ROUTE_IMPORT(ICARUS_GetStringVariable, G_ICARUS_GETSTRINGVARIABLE); + ROUTE_IMPORT(ICARUS_GetVectorVariable, G_ICARUS_GETVECTORVARIABLE); + ROUTE_IMPORT(Nav_Init, G_NAV_INIT); + ROUTE_IMPORT(Nav_Free, G_NAV_FREE); + ROUTE_IMPORT(Nav_Load, G_NAV_LOAD); + ROUTE_IMPORT(Nav_Save, G_NAV_SAVE); + ROUTE_IMPORT(Nav_AddRawPoint, G_NAV_ADDRAWPOINT); + ROUTE_IMPORT(Nav_CalculatePaths, G_NAV_CALCULATEPATHS); + ROUTE_IMPORT(Nav_HardConnect, G_NAV_HARDCONNECT); + ROUTE_IMPORT(Nav_ShowNodes, G_NAV_SHOWNODES); + ROUTE_IMPORT(Nav_ShowEdges, G_NAV_SHOWEDGES); + ROUTE_IMPORT(Nav_ShowPath, G_NAV_SHOWPATH); + ROUTE_IMPORT(Nav_GetNearestNode, G_NAV_GETNEARESTNODE); + ROUTE_IMPORT(Nav_GetBestNode, G_NAV_GETBESTNODE); + ROUTE_IMPORT(Nav_GetNodePosition, G_NAV_GETNODEPOSITION); + ROUTE_IMPORT(Nav_GetNodeNumEdges, G_NAV_GETNODENUMEDGES); + ROUTE_IMPORT(Nav_GetNodeEdge, G_NAV_GETNODEEDGE); + ROUTE_IMPORT(Nav_GetNumNodes, G_NAV_GETNUMNODES); + ROUTE_IMPORT(Nav_Connected, G_NAV_CONNECTED); + ROUTE_IMPORT(Nav_GetPathCost, G_NAV_GETPATHCOST); + ROUTE_IMPORT(Nav_GetEdgeCost, G_NAV_GETEDGECOST); + ROUTE_IMPORT(Nav_GetProjectedNode, G_NAV_GETPROJECTEDNODE); + ROUTE_IMPORT(Nav_CheckFailedNodes, G_NAV_CHECKFAILEDNODES); + ROUTE_IMPORT(Nav_AddFailedNode, G_NAV_ADDFAILEDNODE); + ROUTE_IMPORT(Nav_NodeFailed, G_NAV_NODEFAILED); + ROUTE_IMPORT(Nav_NodesAreNeighbors, G_NAV_NODESARENEIGHBORS); + ROUTE_IMPORT(Nav_ClearFailedEdge, G_NAV_CLEARFAILEDEDGE); + ROUTE_IMPORT(Nav_ClearAllFailedEdges, G_NAV_CLEARALLFAILEDEDGES); + ROUTE_IMPORT(Nav_EdgeFailed, G_NAV_EDGEFAILED); + ROUTE_IMPORT(Nav_AddFailedEdge, G_NAV_ADDFAILEDEDGE); + ROUTE_IMPORT(Nav_CheckFailedEdge, G_NAV_CHECKFAILEDEDGE); + ROUTE_IMPORT(Nav_CheckAllFailedEdges, G_NAV_CHECKALLFAILEDEDGES); + ROUTE_IMPORT(Nav_RouteBlocked, G_NAV_ROUTEBLOCKED); + ROUTE_IMPORT(Nav_GetBestNodeAltRoute, G_NAV_GETBESTNODEALTROUTE); + ROUTE_IMPORT(Nav_GetBestNodeAltRoute2, G_NAV_GETBESTNODEALT2); + ROUTE_IMPORT(Nav_GetBestPathBetweenEnts, G_NAV_GETBESTPATHBETWEENENTS); + ROUTE_IMPORT(Nav_GetNodeRadius, G_NAV_GETNODERADIUS); + ROUTE_IMPORT(Nav_CheckBlockedEdges, G_NAV_CHECKBLOCKEDEDGES); + ROUTE_IMPORT(Nav_ClearCheckedNodes, G_NAV_CLEARCHECKEDNODES); + ROUTE_IMPORT(Nav_CheckedNode, G_NAV_CHECKEDNODE); + ROUTE_IMPORT(Nav_SetCheckedNode, G_NAV_SETCHECKEDNODE); + ROUTE_IMPORT(Nav_FlagAllNodes, G_NAV_FLAGALLNODES); + ROUTE_IMPORT(Nav_GetPathsCalculated, G_NAV_GETPATHSCALCULATED); + ROUTE_IMPORT(Nav_SetPathsCalculated, G_NAV_SETPATHSCALCULATED); + ROUTE_IMPORT(BotAllocateClient, G_BOT_ALLOCATE_CLIENT); + ROUTE_IMPORT(BotFreeClient, G_BOT_FREE_CLIENT); + ROUTE_IMPORT(BotLoadCharacter, BOTLIB_AI_LOAD_CHARACTER); + ROUTE_IMPORT(BotFreeCharacter, BOTLIB_AI_FREE_CHARACTER); + ROUTE_IMPORT(Characteristic_Float, BOTLIB_AI_CHARACTERISTIC_FLOAT); + ROUTE_IMPORT(Characteristic_BFloat, BOTLIB_AI_CHARACTERISTIC_BFLOAT); + ROUTE_IMPORT(Characteristic_Integer, BOTLIB_AI_CHARACTERISTIC_INTEGER); + ROUTE_IMPORT(Characteristic_BInteger, BOTLIB_AI_CHARACTERISTIC_BINTEGER); + ROUTE_IMPORT(Characteristic_String, BOTLIB_AI_CHARACTERISTIC_STRING); + ROUTE_IMPORT(BotAllocChatState, BOTLIB_AI_ALLOC_CHAT_STATE); + ROUTE_IMPORT(BotFreeChatState, BOTLIB_AI_FREE_CHAT_STATE); + ROUTE_IMPORT(BotQueueConsoleMessage, BOTLIB_AI_QUEUE_CONSOLE_MESSAGE); + ROUTE_IMPORT(BotRemoveConsoleMessage, BOTLIB_AI_REMOVE_CONSOLE_MESSAGE); + ROUTE_IMPORT(BotNextConsoleMessage, BOTLIB_AI_NEXT_CONSOLE_MESSAGE); + ROUTE_IMPORT(BotNumConsoleMessages, BOTLIB_AI_NUM_CONSOLE_MESSAGE); + ROUTE_IMPORT(BotInitialChat, BOTLIB_AI_INITIAL_CHAT); + ROUTE_IMPORT(BotReplyChat, BOTLIB_AI_REPLY_CHAT); + ROUTE_IMPORT(BotChatLength, BOTLIB_AI_CHAT_LENGTH); + ROUTE_IMPORT(BotEnterChat, BOTLIB_AI_ENTER_CHAT); + ROUTE_IMPORT(StringContains, BOTLIB_AI_STRING_CONTAINS); + ROUTE_IMPORT(BotFindMatch, BOTLIB_AI_FIND_MATCH); + ROUTE_IMPORT(BotMatchVariable, BOTLIB_AI_MATCH_VARIABLE); + ROUTE_IMPORT(UnifyWhiteSpaces, BOTLIB_AI_UNIFY_WHITE_SPACES); + ROUTE_IMPORT(BotReplaceSynonyms, BOTLIB_AI_REPLACE_SYNONYMS); + ROUTE_IMPORT(BotLoadChatFile, BOTLIB_AI_LOAD_CHAT_FILE); + ROUTE_IMPORT(BotSetChatGender, BOTLIB_AI_SET_CHAT_GENDER); + ROUTE_IMPORT(BotSetChatName, BOTLIB_AI_SET_CHAT_NAME); + ROUTE_IMPORT(BotResetGoalState, BOTLIB_AI_RESET_GOAL_STATE); + ROUTE_IMPORT(BotResetAvoidGoals, BOTLIB_AI_RESET_AVOID_GOALS); + ROUTE_IMPORT(BotPushGoal, BOTLIB_AI_PUSH_GOAL); + ROUTE_IMPORT(BotPopGoal, BOTLIB_AI_POP_GOAL); + ROUTE_IMPORT(BotEmptyGoalStack, BOTLIB_AI_EMPTY_GOAL_STACK); + ROUTE_IMPORT(BotDumpAvoidGoals, BOTLIB_AI_DUMP_AVOID_GOALS); + ROUTE_IMPORT(BotDumpGoalStack, BOTLIB_AI_DUMP_GOAL_STACK); + ROUTE_IMPORT(BotGoalName, BOTLIB_AI_GOAL_NAME); + ROUTE_IMPORT(BotGetTopGoal, BOTLIB_AI_GET_TOP_GOAL); + ROUTE_IMPORT(BotGetSecondGoal, BOTLIB_AI_GET_SECOND_GOAL); + ROUTE_IMPORT(BotChooseLTGItem, BOTLIB_AI_CHOOSE_LTG_ITEM); + ROUTE_IMPORT(BotChooseNBGItem, BOTLIB_AI_CHOOSE_NBG_ITEM); + ROUTE_IMPORT(BotTouchingGoal, BOTLIB_AI_TOUCHING_GOAL); + ROUTE_IMPORT(BotItemGoalInVisButNotVisible, BOTLIB_AI_ITEM_GOAL_IN_VIS_BUT_NOT_VISIBLE); + ROUTE_IMPORT(BotGetLevelItemGoal, BOTLIB_AI_GET_LEVEL_ITEM_GOAL); + ROUTE_IMPORT(BotAvoidGoalTime, BOTLIB_AI_AVOID_GOAL_TIME); + ROUTE_IMPORT(BotInitLevelItems, BOTLIB_AI_INIT_LEVEL_ITEMS); + ROUTE_IMPORT(BotUpdateEntityItems, BOTLIB_AI_UPDATE_ENTITY_ITEMS); + ROUTE_IMPORT(BotLoadItemWeights, BOTLIB_AI_LOAD_ITEM_WEIGHTS); + ROUTE_IMPORT(BotFreeItemWeights, BOTLIB_AI_FREE_ITEM_WEIGHTS); + ROUTE_IMPORT(BotSaveGoalFuzzyLogic, BOTLIB_AI_SAVE_GOAL_FUZZY_LOGIC); + ROUTE_IMPORT(BotAllocGoalState, BOTLIB_AI_ALLOC_GOAL_STATE); + ROUTE_IMPORT(BotFreeGoalState, BOTLIB_AI_FREE_GOAL_STATE); + ROUTE_IMPORT(BotResetMoveState, BOTLIB_AI_RESET_MOVE_STATE); + ROUTE_IMPORT(BotMoveToGoal, BOTLIB_AI_MOVE_TO_GOAL); + ROUTE_IMPORT(BotMoveInDirection, BOTLIB_AI_MOVE_IN_DIRECTION); + ROUTE_IMPORT(BotResetAvoidReach, BOTLIB_AI_RESET_AVOID_REACH); + ROUTE_IMPORT(BotResetLastAvoidReach, BOTLIB_AI_RESET_LAST_AVOID_REACH); + ROUTE_IMPORT(BotReachabilityArea, BOTLIB_AI_REACHABILITY_AREA); + ROUTE_IMPORT(BotMovementViewTarget, BOTLIB_AI_MOVEMENT_VIEW_TARGET); + ROUTE_IMPORT(BotAllocMoveState, BOTLIB_AI_ALLOC_MOVE_STATE); + ROUTE_IMPORT(BotFreeMoveState, BOTLIB_AI_FREE_MOVE_STATE); + ROUTE_IMPORT(BotInitMoveState, BOTLIB_AI_INIT_MOVE_STATE); + ROUTE_IMPORT(BotChooseBestFightWeapon, BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON); + ROUTE_IMPORT(BotGetWeaponInfo, BOTLIB_AI_GET_WEAPON_INFO); + ROUTE_IMPORT(BotLoadWeaponWeights, BOTLIB_AI_LOAD_WEAPON_WEIGHTS); + ROUTE_IMPORT(BotAllocWeaponState, BOTLIB_AI_ALLOC_WEAPON_STATE); + ROUTE_IMPORT(BotFreeWeaponState, BOTLIB_AI_FREE_WEAPON_STATE); + ROUTE_IMPORT(BotResetWeaponState, BOTLIB_AI_RESET_WEAPON_STATE); + ROUTE_IMPORT(GeneticParentsAndChildSelection, BOTLIB_AI_GENETIC_PARENTS_AND_CHILD_SELECTION); + ROUTE_IMPORT(BotInterbreedGoalFuzzyLogic, BOTLIB_AI_INTERBREED_GOAL_FUZZY_LOGIC); + ROUTE_IMPORT(BotMutateGoalFuzzyLogic, BOTLIB_AI_MUTATE_GOAL_FUZZY_LOGIC); + ROUTE_IMPORT(BotGetNextCampSpotGoal, BOTLIB_AI_GET_NEXT_CAMP_SPOT_GOAL); + ROUTE_IMPORT(BotGetMapLocationGoal, BOTLIB_AI_GET_MAP_LOCATION_GOAL); + ROUTE_IMPORT(BotNumInitialChats, BOTLIB_AI_NUM_INITIAL_CHATS); + ROUTE_IMPORT(BotGetChatMessage, BOTLIB_AI_GET_CHAT_MESSAGE); + ROUTE_IMPORT(BotRemoveFromAvoidGoals, BOTLIB_AI_REMOVE_FROM_AVOID_GOALS); + ROUTE_IMPORT(BotPredictVisiblePosition, BOTLIB_AI_PREDICT_VISIBLE_POSITION); + ROUTE_IMPORT(BotSetAvoidGoalTime, BOTLIB_AI_SET_AVOID_GOAL_TIME); + ROUTE_IMPORT(BotAddAvoidSpot, BOTLIB_AI_ADD_AVOID_SPOT); + ROUTE_IMPORT(BotLibSetup, BOTLIB_SETUP); + ROUTE_IMPORT(BotLibShutdown, BOTLIB_SHUTDOWN); + ROUTE_IMPORT(BotLibVarSet, BOTLIB_LIBVAR_SET); + ROUTE_IMPORT(BotLibVarGet, BOTLIB_LIBVAR_GET); + ROUTE_IMPORT(BotLibDefine, BOTLIB_PC_ADD_GLOBAL_DEFINE); + ROUTE_IMPORT(BotLibStartFrame, BOTLIB_START_FRAME); + ROUTE_IMPORT(BotLibLoadMap, BOTLIB_LOAD_MAP); + ROUTE_IMPORT(BotLibUpdateEntity, BOTLIB_UPDATENTITY); + ROUTE_IMPORT(BotLibTest, BOTLIB_TEST); + ROUTE_IMPORT(BotGetSnapshotEntity, BOTLIB_GET_SNAPSHOT_ENTITY); + ROUTE_IMPORT(BotGetServerCommand, BOTLIB_GET_CONSOLE_MESSAGE); + ROUTE_IMPORT(BotUserCommand, BOTLIB_USER_COMMAND); + ROUTE_IMPORT(BotUpdateWaypoints, G_BOT_UPDATEWAYPOINTS); + ROUTE_IMPORT(BotCalculatePaths, G_BOT_CALCULATEPATHS); + ROUTE_IMPORT(AAS_EnableRoutingArea, BOTLIB_AAS_ENABLE_ROUTING_AREA); + ROUTE_IMPORT(AAS_BBoxAreas, BOTLIB_AAS_BBOX_AREAS); + ROUTE_IMPORT(AAS_AreaInfo, BOTLIB_AAS_AREA_INFO); + ROUTE_IMPORT(AAS_EntityInfo, BOTLIB_AAS_ENTITY_INFO); + ROUTE_IMPORT(AAS_Initialized, BOTLIB_AAS_INITIALIZED); + ROUTE_IMPORT(AAS_PresenceTypeBoundingBox, BOTLIB_AAS_PRESENCE_TYPE_BOUNDING_BOX); + ROUTE_IMPORT(AAS_Time, BOTLIB_AAS_TIME); + ROUTE_IMPORT(AAS_PointAreaNum, BOTLIB_AAS_POINT_AREA_NUM); + ROUTE_IMPORT(AAS_TraceAreas, BOTLIB_AAS_TRACE_AREAS); + ROUTE_IMPORT(AAS_PointContents, BOTLIB_AAS_POINT_CONTENTS); + ROUTE_IMPORT(AAS_NextBSPEntity, BOTLIB_AAS_NEXT_BSP_ENTITY); + ROUTE_IMPORT(AAS_ValueForBSPEpairKey, BOTLIB_AAS_VALUE_FOR_BSP_EPAIR_KEY); + ROUTE_IMPORT(AAS_VectorForBSPEpairKey, BOTLIB_AAS_VECTOR_FOR_BSP_EPAIR_KEY); + ROUTE_IMPORT(AAS_FloatForBSPEpairKey, BOTLIB_AAS_FLOAT_FOR_BSP_EPAIR_KEY); + ROUTE_IMPORT(AAS_IntForBSPEpairKey, BOTLIB_AAS_INT_FOR_BSP_EPAIR_KEY); + ROUTE_IMPORT(AAS_AreaReachability, BOTLIB_AAS_AREA_REACHABILITY); + ROUTE_IMPORT(AAS_AreaTravelTimeToGoalArea, BOTLIB_AAS_AREA_TRAVEL_TIME_TO_GOAL_AREA); + ROUTE_IMPORT(AAS_Swimming, BOTLIB_AAS_SWIMMING); + ROUTE_IMPORT(AAS_PredictClientMovement, BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT); + ROUTE_IMPORT(AAS_AlternativeRouteGoals, BOTLIB_AAS_ALTERNATIVE_ROUTE_GOAL); + ROUTE_IMPORT(AAS_PredictRoute, BOTLIB_AAS_PREDICT_ROUTE); + ROUTE_IMPORT(AAS_PointReachabilityAreaIndex, BOTLIB_AAS_POINT_REACHABILITY_AREA_INDEX); + ROUTE_IMPORT(EA_Say, BOTLIB_EA_SAY); + ROUTE_IMPORT(EA_SayTeam, BOTLIB_EA_SAY_TEAM); + ROUTE_IMPORT(EA_Command, BOTLIB_EA_COMMAND); + ROUTE_IMPORT(EA_Action, BOTLIB_EA_ACTION); + ROUTE_IMPORT(EA_Gesture, BOTLIB_EA_GESTURE); + ROUTE_IMPORT(EA_Talk, BOTLIB_EA_TALK); + ROUTE_IMPORT(EA_Attack, BOTLIB_EA_ATTACK); + ROUTE_IMPORT(EA_Alt_Attack, BOTLIB_EA_ALT_ATTACK); + ROUTE_IMPORT(EA_ForcePower, BOTLIB_EA_FORCEPOWER); + ROUTE_IMPORT(EA_Use, BOTLIB_EA_USE); + ROUTE_IMPORT(EA_Respawn, BOTLIB_EA_RESPAWN); + ROUTE_IMPORT(EA_Crouch, BOTLIB_EA_CROUCH); + ROUTE_IMPORT(EA_MoveUp, BOTLIB_EA_MOVE_UP); + ROUTE_IMPORT(EA_MoveDown, BOTLIB_EA_MOVE_DOWN); + ROUTE_IMPORT(EA_MoveForward, BOTLIB_EA_MOVE_FORWARD); + ROUTE_IMPORT(EA_MoveBack, BOTLIB_EA_MOVE_BACK); + ROUTE_IMPORT(EA_MoveLeft, BOTLIB_EA_MOVE_LEFT); + ROUTE_IMPORT(EA_MoveRight, BOTLIB_EA_MOVE_RIGHT); + ROUTE_IMPORT(EA_SelectWeapon, BOTLIB_EA_SELECT_WEAPON); + ROUTE_IMPORT(EA_Jump, BOTLIB_EA_JUMP); + ROUTE_IMPORT(EA_DelayedJump, BOTLIB_EA_DELAYED_JUMP); + ROUTE_IMPORT(EA_Move, BOTLIB_EA_MOVE); + ROUTE_IMPORT(EA_View, BOTLIB_EA_VIEW); + ROUTE_IMPORT(EA_EndRegular, BOTLIB_EA_END_REGULAR); + ROUTE_IMPORT(EA_GetInput, BOTLIB_EA_GET_INPUT); + ROUTE_IMPORT(EA_ResetInput, BOTLIB_EA_RESET_INPUT); + ROUTE_IMPORT(PC_LoadSource, BOTLIB_PC_LOAD_SOURCE); + ROUTE_IMPORT(PC_FreeSource, BOTLIB_PC_FREE_SOURCE); + ROUTE_IMPORT(PC_ReadToken, BOTLIB_PC_READ_TOKEN); + ROUTE_IMPORT(PC_SourceFileAndLine, BOTLIB_PC_SOURCE_FILE_AND_LINE); + ROUTE_IMPORT(R_RegisterSkin, G_R_REGISTERSKIN); + ROUTE_IMPORT(SetActiveSubBSP, G_SET_ACTIVE_SUBBSP); + ROUTE_IMPORT(CM_RegisterTerrain, G_CM_REGISTER_TERRAIN); + ROUTE_IMPORT(RMG_Init, G_RMG_INIT); + ROUTE_IMPORT(G2API_ListModelBones, G_G2_LISTBONES); + ROUTE_IMPORT(G2API_ListModelSurfaces, G_G2_LISTSURFACES); + ROUTE_IMPORT(G2API_HaveWeGhoul2Models, G_G2_HAVEWEGHOULMODELS); + ROUTE_IMPORT(G2API_SetGhoul2ModelIndexes, G_G2_SETMODELS); + ROUTE_IMPORT(G2API_GetBoltMatrix, G_G2_GETBOLT); + ROUTE_IMPORT(G2API_GetBoltMatrix_NoReconstruct, G_G2_GETBOLT_NOREC); + ROUTE_IMPORT(G2API_GetBoltMatrix_NoRecNoRot, G_G2_GETBOLT_NOREC_NOROT); + ROUTE_IMPORT(G2API_InitGhoul2Model, G_G2_INITGHOUL2MODEL); + ROUTE_IMPORT(G2API_SetSkin, G_G2_SETSKIN); + ROUTE_IMPORT(G2API_Ghoul2Size, G_G2_SIZE); + ROUTE_IMPORT(G2API_AddBolt, G_G2_ADDBOLT); + ROUTE_IMPORT(G2API_SetBoltInfo, G_G2_SETBOLTINFO); + ROUTE_IMPORT(G2API_SetBoneAngles, G_G2_ANGLEOVERRIDE); + ROUTE_IMPORT(G2API_SetBoneAnim, G_G2_PLAYANIM); + ROUTE_IMPORT(G2API_GetBoneAnim, G_G2_GETBONEANIM); + ROUTE_IMPORT(G2API_GetGLAName, G_G2_GETGLANAME); + ROUTE_IMPORT(G2API_CopyGhoul2Instance, G_G2_COPYGHOUL2INSTANCE); + ROUTE_IMPORT(G2API_CopySpecificGhoul2Model, G_G2_COPYSPECIFICGHOUL2MODEL); + ROUTE_IMPORT(G2API_DuplicateGhoul2Instance, G_G2_DUPLICATEGHOUL2INSTANCE); + ROUTE_IMPORT(G2API_HasGhoul2ModelOnIndex, G_G2_HASGHOUL2MODELONINDEX); + ROUTE_IMPORT(G2API_RemoveGhoul2Model, G_G2_REMOVEGHOUL2MODEL); + ROUTE_IMPORT(G2API_RemoveGhoul2Models, G_G2_REMOVEGHOUL2MODELS); + ROUTE_IMPORT(G2API_CleanGhoul2Models, G_G2_CLEANMODELS); + ROUTE_IMPORT(G2API_CollisionDetect, G_G2_COLLISIONDETECT); + ROUTE_IMPORT(G2API_CollisionDetectCache, G_G2_COLLISIONDETECTCACHE); + ROUTE_IMPORT(G2API_SetRootSurface, G_G2_SETROOTSURFACE); + ROUTE_IMPORT(G2API_SetSurfaceOnOff, G_G2_SETSURFACEONOFF); + ROUTE_IMPORT(G2API_SetNewOrigin, G_G2_SETNEWORIGIN); + ROUTE_IMPORT(G2API_DoesBoneExist, G_G2_DOESBONEEXIST); + ROUTE_IMPORT(G2API_GetSurfaceRenderStatus, G_G2_GETSURFACERENDERSTATUS); + ROUTE_IMPORT(G2API_AbsurdSmoothing, G_G2_ABSURDSMOOTHING); + ROUTE_IMPORT(G2API_SetRagDoll, G_G2_SETRAGDOLL); + ROUTE_IMPORT(G2API_AnimateG2Models, G_G2_ANIMATEG2MODELS); + ROUTE_IMPORT(G2API_RagPCJConstraint, G_G2_RAGPCJCONSTRAINT); + ROUTE_IMPORT(G2API_RagPCJGradientSpeed, G_G2_RAGPCJGRADIENTSPEED); + ROUTE_IMPORT(G2API_RagEffectorGoal, G_G2_RAGEFFECTORGOAL); + ROUTE_IMPORT(G2API_GetRagBonePos, G_G2_GETRAGBONEPOS); + ROUTE_IMPORT(G2API_RagEffectorKick, G_G2_RAGEFFECTORKICK); + ROUTE_IMPORT(G2API_RagForceSolve, G_G2_RAGFORCESOLVE); + ROUTE_IMPORT(G2API_SetBoneIKState, G_G2_SETBONEIKSTATE); + ROUTE_IMPORT(G2API_IKMove, G_G2_IKMOVE); + ROUTE_IMPORT(G2API_RemoveBone, G_G2_REMOVEBONE); + ROUTE_IMPORT(G2API_AttachInstanceToEntNum, G_G2_ATTACHINSTANCETOENTNUM); + ROUTE_IMPORT(G2API_ClearAttachedInstance, G_G2_CLEARATTACHEDINSTANCE); + ROUTE_IMPORT(G2API_CleanEntAttachments, G_G2_CLEANENTATTACHMENTS); + ROUTE_IMPORT(G2API_OverrideServer, G_G2_OVERRIDESERVER); + ROUTE_IMPORT(G2API_GetSurfaceName, G_G2_GETSURFACENAME); + + // handle special cmds which QMM uses but JAMP doesn't have an analogue for + case G_ARGS: { + // quake2: char* (*args)(void); + static std::string s; + static char buf[MAX_STRING_CHARS]; + s = ""; + int i = 1; + while (i < orig_import.Argc()) { + orig_import.Argv(i, buf, sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + if (i != 1) + s += " "; + s += buf; + } + ret = (intptr_t)s.c_str(); + break; + } + + default: + break; + }; + } // do anything that needs to be done after function call here #ifdef _DEBUG if (cmd != G_PRINT) - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall_GGA({} {}) returning {}\n", JAMP_eng_msg_names(cmd), cmd, ret); + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_syscall({} {}) returning {}\n", JAMP_eng_msg_names(cmd), cmd, ret); #endif return ret; @@ -886,82 +825,97 @@ static intptr_t JAMP_syscall_GGA(intptr_t cmd, ...) { // wrapper vmMain function that calls actual mod func from orig_export // this is how QMM and plugins will call into the mod -static intptr_t JAMP_vmMain_GGA(intptr_t cmd, ...) { +static intptr_t JAMP_vmMain(intptr_t cmd, ...) { QMM_GET_VMMAIN_ARGS(); #ifdef _DEBUG - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain_GGA({} {}) called\n", JAMP_mod_msg_names(cmd), cmd); + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain({} {}) called\n", JAMP_mod_msg_names(cmd), cmd); #endif - if (!s_is_GetGameAPI) - return 0; - - if (!orig_export) - return 0; - // store return value since we do some stuff after the function call is over intptr_t ret = 0; - switch (cmd) { - ROUTE_EXPORT(InitGame, GAME_INIT); - ROUTE_EXPORT(ShutdownGame, GAME_SHUTDOWN); - ROUTE_EXPORT(ClientConnect, GAME_CLIENT_CONNECT); - ROUTE_EXPORT(ClientBegin, GAME_CLIENT_BEGIN); - ROUTE_EXPORT(ClientUserinfoChanged, GAME_CLIENT_USERINFO_CHANGED); - ROUTE_EXPORT(ClientDisconnect, GAME_CLIENT_DISCONNECT); - ROUTE_EXPORT(ClientCommand, GAME_CLIENT_COMMAND); - ROUTE_EXPORT(ClientThink, GAME_CLIENT_THINK); - ROUTE_EXPORT(RunFrame, GAME_RUN_FRAME); - ROUTE_EXPORT(ConsoleCommand, GAME_CONSOLE_COMMAND); - ROUTE_EXPORT(BotAIStartFrame, BOTAI_START_FRAME); - ROUTE_EXPORT(ROFF_NotetrackCallback, GAME_ROFF_NOTETRACK_CALLBACK); - ROUTE_EXPORT(SpawnRMGEntity, GAME_SPAWN_RMG_ENTITY); - ROUTE_EXPORT(ICARUS_PlaySound, GAME_ICARUS_PLAYSOUND); - ROUTE_EXPORT(ICARUS_Set, GAME_ICARUS_SET); - ROUTE_EXPORT(ICARUS_Lerp2Pos, GAME_ICARUS_LERP2POS); - ROUTE_EXPORT(ICARUS_Lerp2Origin, GAME_ICARUS_LERP2ORIGIN); - ROUTE_EXPORT(ICARUS_Lerp2Angles, GAME_ICARUS_LERP2ANGLES); - ROUTE_EXPORT(ICARUS_GetTag, GAME_ICARUS_GETTAG); - ROUTE_EXPORT(ICARUS_Lerp2Start, GAME_ICARUS_LERP2START); - ROUTE_EXPORT(ICARUS_Lerp2End, GAME_ICARUS_LERP2END); - ROUTE_EXPORT(ICARUS_Use, GAME_ICARUS_USE); - ROUTE_EXPORT(ICARUS_Kill, GAME_ICARUS_KILL); - ROUTE_EXPORT(ICARUS_Remove, GAME_ICARUS_REMOVE); - ROUTE_EXPORT(ICARUS_Play, GAME_ICARUS_PLAY); - ROUTE_EXPORT(ICARUS_GetFloat, GAME_ICARUS_GETFLOAT); - ROUTE_EXPORT(ICARUS_GetVector, GAME_ICARUS_GETVECTOR); - ROUTE_EXPORT(ICARUS_GetString, GAME_ICARUS_GETSTRING); - ROUTE_EXPORT(ICARUS_SoundIndex, GAME_ICARUS_SOUNDINDEX); - ROUTE_EXPORT(ICARUS_GetSetIDForString, GAME_ICARUS_GETSETIDFORSTRING); - ROUTE_EXPORT(NAV_ClearPathToPoint, GAME_NAV_CLEARPATHTOPOINT); - ROUTE_EXPORT(NPC_ClearLOS2, GAME_NAV_CLEARLOS); - ROUTE_EXPORT(NAVNEW_ClearPathBetweenPoints, GAME_NAV_CLEARPATHBETWEENPOINTS); - ROUTE_EXPORT(NAV_CheckNodeFailedForEnt, GAME_NAV_CHECKNODEFAILEDFORENT); - ROUTE_EXPORT(NAV_EntIsUnlockedDoor, GAME_NAV_ENTISUNLOCKEDDOOR); - ROUTE_EXPORT(NAV_EntIsDoor, GAME_NAV_ENTISDOOR); - ROUTE_EXPORT(NAV_EntIsBreakable, GAME_NAV_ENTISBREAKABLE); - ROUTE_EXPORT(NAV_EntIsRemovableUsable, GAME_NAV_ENTISREMOVABLEUSABLE); - ROUTE_EXPORT(NAV_FindCombatPointWaypoints, GAME_NAV_FINDCOMBATPOINTWAYPOINTS); - ROUTE_EXPORT(BG_GetItemIndexByTag, GAME_GETITEMINDEXBYTAG); - - default: - break; - }; + // if QMM was loaded with the official JAMP or OpenJK "legacy" API (which shouldn't happen, but whatever) + if (orig_vmMain) { + // all normal mod functions go to mod + ret = orig_vmMain(cmd, QMM_PUT_VMMAIN_ARGS()); + } + // if QMM was loaded with the OpenJK "new" API + else if (orig_export) { + switch (cmd) { + ROUTE_EXPORT(InitGame, GAME_INIT); + ROUTE_EXPORT(ShutdownGame, GAME_SHUTDOWN); + ROUTE_EXPORT(ClientConnect, GAME_CLIENT_CONNECT); + ROUTE_EXPORT(ClientBegin, GAME_CLIENT_BEGIN); + ROUTE_EXPORT(ClientUserinfoChanged, GAME_CLIENT_USERINFO_CHANGED); + ROUTE_EXPORT(ClientDisconnect, GAME_CLIENT_DISCONNECT); + ROUTE_EXPORT(ClientCommand, GAME_CLIENT_COMMAND); + ROUTE_EXPORT(ClientThink, GAME_CLIENT_THINK); + ROUTE_EXPORT(RunFrame, GAME_RUN_FRAME); + ROUTE_EXPORT(ConsoleCommand, GAME_CONSOLE_COMMAND); + ROUTE_EXPORT(BotAIStartFrame, BOTAI_START_FRAME); + ROUTE_EXPORT(ROFF_NotetrackCallback, GAME_ROFF_NOTETRACK_CALLBACK); + ROUTE_EXPORT(SpawnRMGEntity, GAME_SPAWN_RMG_ENTITY); + ROUTE_EXPORT(ICARUS_PlaySound, GAME_ICARUS_PLAYSOUND); + ROUTE_EXPORT(ICARUS_Set, GAME_ICARUS_SET); + ROUTE_EXPORT(ICARUS_Lerp2Pos, GAME_ICARUS_LERP2POS); + ROUTE_EXPORT(ICARUS_Lerp2Origin, GAME_ICARUS_LERP2ORIGIN); + ROUTE_EXPORT(ICARUS_Lerp2Angles, GAME_ICARUS_LERP2ANGLES); + ROUTE_EXPORT(ICARUS_GetTag, GAME_ICARUS_GETTAG); + ROUTE_EXPORT(ICARUS_Lerp2Start, GAME_ICARUS_LERP2START); + ROUTE_EXPORT(ICARUS_Lerp2End, GAME_ICARUS_LERP2END); + ROUTE_EXPORT(ICARUS_Use, GAME_ICARUS_USE); + ROUTE_EXPORT(ICARUS_Kill, GAME_ICARUS_KILL); + ROUTE_EXPORT(ICARUS_Remove, GAME_ICARUS_REMOVE); + ROUTE_EXPORT(ICARUS_Play, GAME_ICARUS_PLAY); + ROUTE_EXPORT(ICARUS_GetFloat, GAME_ICARUS_GETFLOAT); + ROUTE_EXPORT(ICARUS_GetVector, GAME_ICARUS_GETVECTOR); + ROUTE_EXPORT(ICARUS_GetString, GAME_ICARUS_GETSTRING); + ROUTE_EXPORT(ICARUS_SoundIndex, GAME_ICARUS_SOUNDINDEX); + ROUTE_EXPORT(ICARUS_GetSetIDForString, GAME_ICARUS_GETSETIDFORSTRING); + ROUTE_EXPORT(NAV_ClearPathToPoint, GAME_NAV_CLEARPATHTOPOINT); + ROUTE_EXPORT(NPC_ClearLOS2, GAME_NAV_CLEARLOS); + ROUTE_EXPORT(NAVNEW_ClearPathBetweenPoints, GAME_NAV_CLEARPATHBETWEENPOINTS); + ROUTE_EXPORT(NAV_CheckNodeFailedForEnt, GAME_NAV_CHECKNODEFAILEDFORENT); + ROUTE_EXPORT(NAV_EntIsUnlockedDoor, GAME_NAV_ENTISUNLOCKEDDOOR); + ROUTE_EXPORT(NAV_EntIsDoor, GAME_NAV_ENTISDOOR); + ROUTE_EXPORT(NAV_EntIsBreakable, GAME_NAV_ENTISBREAKABLE); + ROUTE_EXPORT(NAV_EntIsRemovableUsable, GAME_NAV_ENTISREMOVABLEUSABLE); + ROUTE_EXPORT(NAV_FindCombatPointWaypoints, GAME_NAV_FINDCOMBATPOINTWAYPOINTS); + ROUTE_EXPORT(BG_GetItemIndexByTag, GAME_GETITEMINDEXBYTAG); + + default: + break; + }; + } #ifdef _DEBUG - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain_GGA({} {}) returning {}\n", JAMP_mod_msg_names(cmd), cmd, ret); + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_vmMain({} {}) returning {}\n", JAMP_mod_msg_names(cmd), cmd, ret); #endif return ret; } -static void* JAMP_GetGameAPI(void* apiversion, void* import) { - orig_apiversion_GGA = (intptr_t)apiversion; - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_GetGameAPI({}, {}) called\n", orig_apiversion_GGA, import); +static void JAMP_dllEntry(eng_syscall syscall) { + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_dllEntry({}) called\n", (void*)syscall); + + // store original syscall from engine + orig_syscall = syscall; - // store how we were loaded - s_is_GetGameAPI = true; + // pointer to wrapper vmMain function that calls either orig_vmMain or func in orig_export + g_gameinfo.pfnvmMain = JAMP_vmMain; + + // pointer to wrapper syscall function that calls either orig_syscall or func in orig_import + g_gameinfo.pfnsyscall = JAMP_syscall; + + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_dllEntry({}) returning\n", (void*)syscall); +} + + +static void* JAMP_GetGameAPI(void* apiversion, void* import) { + orig_apiversion = (intptr_t)apiversion; + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_GetGameAPI({}, {}) called\n", orig_apiversion, import); // original import struct from engine // the struct given by the engine goes out of scope after this returns so we have to copy the whole thing @@ -970,13 +924,13 @@ static void* JAMP_GetGameAPI(void* apiversion, void* import) { // fill in variables of our hooked import struct to pass to the mod - // pointer to wrapper vmMain function that calls actual mod func from orig_export - g_gameinfo.pfnvmMain = JAMP_vmMain_GGA; + // pointer to wrapper vmMain function that calls either orig_vmMain or func in orig_export + g_gameinfo.pfnvmMain = JAMP_vmMain; - // pointer to wrapper syscall function that calls actual engine func from orig_import - g_gameinfo.pfnsyscall = JAMP_syscall_GGA; + // pointer to wrapper syscall function that calls either orig_syscall or func in orig_import + g_gameinfo.pfnsyscall = JAMP_syscall; - LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_GetGameAPI({}, {}) returning {}\n", orig_apiversion_GGA, import, (void*)&qmm_export); + LOG(QMM_LOG_DEBUG, "QMM") << fmt::format("JAMP_GetGameAPI({}, {}) returning {}\n", orig_apiversion, import, (void*)&qmm_export); // struct full of export lambdas to QMM's vmMain // this gets returned to the game engine, but we haven't loaded the mod yet. @@ -986,24 +940,24 @@ static void* JAMP_GetGameAPI(void* apiversion, void* import) { } -static bool JAMP_mod_load(void* entry) { - if (s_is_GetGameAPI) { +static bool JAMP_mod_load(void* entry, bool is_GetGameAPI) { + if (is_GetGameAPI) { mod_GetGameAPI pfnGGA = (mod_GetGameAPI)entry; // api version gets passed before import pointer - orig_export = (game_export_t*)pfnGGA((void*)orig_apiversion_GGA, &qmm_import); + orig_export = (game_export_t*)pfnGGA((void*)orig_apiversion, &qmm_import); return !!orig_export; } else { - orig_vmMain_legacy = (mod_vmMain)entry; - return !!orig_vmMain_legacy; + orig_vmMain = (mod_vmMain)entry; + return !!orig_vmMain; } } static void JAMP_mod_unload() { orig_export = nullptr; - orig_vmMain_legacy = nullptr; + orig_vmMain = nullptr; } @@ -1340,9 +1294,6 @@ static const char* JAMP_eng_msg_names(intptr_t cmd) { GEN_CASE(G_BOT_UPDATEWAYPOINTS); GEN_CASE(G_BOT_CALCULATEPATHS); - // OpenJK-only - GEN_CASE(G_SV_REGISTER_SHARED_MEMORY); - // polyfills GEN_CASE(G_ARGS); default: From c7f5433381331186924b49511e313ba9042c4e80 Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 21:04:32 +0200 Subject: [PATCH 11/12] switch back COD11MP to using GEN_DLL macro, and have an autodetect function that always returns false --- src/game_cod11mp.cpp | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/game_cod11mp.cpp b/src/game_cod11mp.cpp index b076f03..8db53a6 100644 --- a/src/game_cod11mp.cpp +++ b/src/game_cod11mp.cpp @@ -20,23 +20,13 @@ Created By: GEN_QMM_MSGS(COD11MP); GEN_EXTS(COD11MP); -static const char* COD11MP_eng_msg_names(intptr_t); -static const char* COD11MP_mod_msg_names(intptr_t); -static void COD11MP_dllEntry(eng_syscall); -static bool COD11MP_mod_load(void*, bool); -static void COD11MP_mod_unload(); -supportedgame_funcs COD11MP_funcs = { - COD11MP_qmm_eng_msgs, - COD11MP_qmm_mod_msgs, - COD11MP_eng_msg_names, - COD11MP_mod_msg_names, - nullptr, // COD11MP_autodetect - nullptr, // COD11MP_qvmsyscall - COD11MP_dllEntry, - nullptr, // COD11MP_GetGameAPI - COD11MP_mod_load, - COD11MP_mod_unload -}; +GEN_DLL(COD11MP); + + +// auto-detection logic for COD11MP (never auto-detect) +static bool COD11MP_autodetect(bool, supportedgame*) { + return false; +} // original syscall pointer that comes from the game engine From 33e51c4731cfeb11e3ee9012a35c8c11b83d4fdc Mon Sep 17 00:00:00 2001 From: Kevin Masterson Date: Thu, 5 Mar 2026 23:25:00 +0200 Subject: [PATCH 12/12] add alias G_FS_LISTFILES for G_FS_GETFILELIST --- include/game_jamp.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/game_jamp.h b/include/game_jamp.h index bd97b8f..075d047 100644 --- a/include/game_jamp.h +++ b/include/game_jamp.h @@ -12,6 +12,11 @@ Created By: #ifndef QMM2_GAME_JAMP_H #define QMM2_GAME_JAMP_H +// meh +enum { + G_FS_LISTFILES = G_FS_GETFILELIST, +}; + // these import messages do not have an exact analogue in JAMP enum { G_ARGS = -100, // char* (void)