From 492aac484b5c65e5df21a7d1b1cf781063efef50 Mon Sep 17 00:00:00 2001 From: Matthew Wozniak Date: Sun, 3 Nov 2024 00:20:45 -0400 Subject: purge CR from this project --- api.c | 166 +++++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 83 insertions(+), 83 deletions(-) (limited to 'api.c') diff --git a/api.c b/api.c index b24514e..563b1cc 100644 --- a/api.c +++ b/api.c @@ -1,83 +1,83 @@ -// SPDX-License-Identifier: ISC -// SPDX-FileCopyrightText: 2024 Matthew Wozniak - -#define NO_EXTERNS -#include "api.h" -#undef NO_EXTERNS -#include "os.h" -#include "log.h" -#include "sst/x86.h" - -struct engserver *engserver = NULL; -struct engclient *engclient = NULL; -struct engineapi *engineapi = NULL; -struct enginetools *enginetools = NULL; -struct demoplayer *demoplayer = NULL; -struct videomode **videomode = NULL; -struct movieinfo *movieinfo = NULL; -void (*cbuf_addtext)(char *) = NULL; - -// TODO: should this be split up? - -bool api_init(void) { - void *engine_dll = os_dlhandle("engine"); - createinterface_func engine_factory = - (createinterface_func)os_dlsym(engine_dll, "CreateInterface"); - if (!engine_factory) bail("couldn't get engine factory"); - engserver = engine_factory(VENGINE_SERVER_INTERFACE_VERSION, NULL); - if (!engserver) bail("couldn't get IVEngineServer from engine"); - engclient = engine_factory(VENGINE_CLIENT_INTERFACE_VERSION, NULL); - if (!engclient) bail("couldn't get IVEngineClient from engine"); - engineapi = engine_factory(VENGINE_LAUNCHER_INTERFACE_VERSION, NULL); - if (!engineapi) bail("couldn't get IEngineAPI from engine"); - enginetools = engine_factory(VENGINE_TOOL_INTERFACE_VERSION, NULL); - if (!engineapi) bail("couldn't get IEngineTools from engine"); - - // find cbuf_addtext - const u8 *instr = (const u8 *)engserver->vt->server_command; - // ServerCommand() calls a few small functions before Cbuf_AddText but they - // get inlined. look for 'push esi' and then a call. - for (const u8 *p = instr; p - instr < 64;) { - if (*p == X86_PUSHESI && *++p == X86_CALL) { - // jump is relative to after the instruction - cbuf_addtext = (void (*)(char *))(p + 5 + *(i32 *)(p + 1)); - } - int l = x86_len(p); - if (l == -1) - bail("invalid instruction looking for cbuf_addtext"); - p += l; - } - if (!cbuf_addtext) bail("couldn't find cbuf_addtext"); - - // find demoplayer - instr = (const u8 *)engclient->vt->is_playing_demo; - // CEngineClient::IsPlayingDemo is a wrapper around a demoplayer call - // The first thing it does should be load a ptr to demoplayer into ECX - if (instr[0] != X86_MOVRMW || instr[1] != X86_MODRM(0, 1, 5)) - bail("couldn't get demoplayer"); - demoplayer = **(struct demoplayer ***)(instr + 2); - debug("demoplayer = %p", (void *)demoplayer); - - // find videomode - // CEngineAPI::SetEngineWindow calls videomode->SetGameWindow after - // detaching the current window with another vcall. Look for the second one. - // This, like the demoplayer, is a pointer. Mind the double dereference. - instr = (const u8 *)engineapi->vt->set_engine_window; - int mov_ecx_counter = 0; - for (const u8 *p = instr; p - instr < 64;) { - if (p[0] == X86_MOVRMW && p[1] == X86_MODRM(0, 1, 5) - && ++mov_ecx_counter == 2) { - videomode = *(struct videomode ***)(p + 2); - break; - } - int l = x86_len(p); - if (l == -1) - bail("invalid instruction looking for videomode"); - p += l; - } - debug("videomode = %p", (void *)videomode); - - return true; -} - -// vi: sw=4 ts=4 noet tw=80 cc=80 +// SPDX-License-Identifier: ISC +// SPDX-FileCopyrightText: 2024 Matthew Wozniak + +#define NO_EXTERNS +#include "api.h" +#undef NO_EXTERNS +#include "os.h" +#include "log.h" +#include "sst/x86.h" + +struct engserver *engserver = NULL; +struct engclient *engclient = NULL; +struct engineapi *engineapi = NULL; +struct enginetools *enginetools = NULL; +struct demoplayer *demoplayer = NULL; +struct videomode **videomode = NULL; +struct movieinfo *movieinfo = NULL; +void (*cbuf_addtext)(char *) = NULL; + +// TODO: should this be split up? + +bool api_init(void) { + void *engine_dll = os_dlhandle("engine"); + createinterface_func engine_factory = + (createinterface_func)os_dlsym(engine_dll, "CreateInterface"); + if (!engine_factory) bail("couldn't get engine factory"); + engserver = engine_factory(VENGINE_SERVER_INTERFACE_VERSION, NULL); + if (!engserver) bail("couldn't get IVEngineServer from engine"); + engclient = engine_factory(VENGINE_CLIENT_INTERFACE_VERSION, NULL); + if (!engclient) bail("couldn't get IVEngineClient from engine"); + engineapi = engine_factory(VENGINE_LAUNCHER_INTERFACE_VERSION, NULL); + if (!engineapi) bail("couldn't get IEngineAPI from engine"); + enginetools = engine_factory(VENGINE_TOOL_INTERFACE_VERSION, NULL); + if (!engineapi) bail("couldn't get IEngineTools from engine"); + + // find cbuf_addtext + const u8 *instr = (const u8 *)engserver->vt->server_command; + // ServerCommand() calls a few small functions before Cbuf_AddText but they + // get inlined. look for 'push esi' and then a call. + for (const u8 *p = instr; p - instr < 64;) { + if (*p == X86_PUSHESI && *++p == X86_CALL) { + // jump is relative to after the instruction + cbuf_addtext = (void (*)(char *))(p + 5 + *(i32 *)(p + 1)); + } + int l = x86_len(p); + if (l == -1) + bail("invalid instruction looking for cbuf_addtext"); + p += l; + } + if (!cbuf_addtext) bail("couldn't find cbuf_addtext"); + + // find demoplayer + instr = (const u8 *)engclient->vt->is_playing_demo; + // CEngineClient::IsPlayingDemo is a wrapper around a demoplayer call + // The first thing it does should be load a ptr to demoplayer into ECX + if (instr[0] != X86_MOVRMW || instr[1] != X86_MODRM(0, 1, 5)) + bail("couldn't get demoplayer"); + demoplayer = **(struct demoplayer ***)(instr + 2); + debug("demoplayer = %p", (void *)demoplayer); + + // find videomode + // CEngineAPI::SetEngineWindow calls videomode->SetGameWindow after + // detaching the current window with another vcall. Look for the second one. + // This, like the demoplayer, is a pointer. Mind the double dereference. + instr = (const u8 *)engineapi->vt->set_engine_window; + int mov_ecx_counter = 0; + for (const u8 *p = instr; p - instr < 64;) { + if (p[0] == X86_MOVRMW && p[1] == X86_MODRM(0, 1, 5) + && ++mov_ecx_counter == 2) { + videomode = *(struct videomode ***)(p + 2); + break; + } + int l = x86_len(p); + if (l == -1) + bail("invalid instruction looking for videomode"); + p += l; + } + debug("videomode = %p", (void *)videomode); + + return true; +} + +// vi: sw=4 ts=4 noet tw=80 cc=80 -- cgit v1.2.3-54-g00ecf