diff options
Diffstat (limited to 'api.c')
-rw-r--r-- | api.c | 32 |
1 files changed, 31 insertions, 1 deletions
@@ -74,7 +74,9 @@ bool api_init(void) { // 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. + // This, like the demoplayer, is a pointer. We need to keep the double + // pointer because when we get this, it is null. It is set by the engine + // later. instr = (const u8 *)engineapi->vt->set_engine_window; int mov_ecx_counter = 0; for (const u8 *p = instr; p - instr < 64;) { @@ -89,6 +91,34 @@ bool api_init(void) { p += l; } debug("videomode = %p", (void *)videomode); + + // find cl_movieinfo + { + // step 1: find CL_IsRecordingMovie() in + // CEngineTools::StartMovieRecording + instr = (const u8 *)enginetools->vt->start_movie_recording; + void *cl_isrecordingmovie = NULL; + for (const u8 *p = instr; p - instr < 64;) { + // this is the first call in the function + if (*p == X86_CALL) { + cl_isrecordingmovie = (void *)(p + 5 + *(i32 *)(p + 1)); + } + int l = x86_len(p); + if (l == -1) + bail("invalid instruction looking for CL_IsRecordingMovie"); + p += l; + } + if (!cl_isrecordingmovie) + bail("couldn't find cbuf_addtext CL_IsRecordingMovie"); + + // step 2: get the pointer to cl_movieinfo + // should be in the first instruction + instr = (const u8 *)cl_isrecordingmovie; + if (instr[0] != X86_ALUMI8 || instr[1] != X86_MODRM(0, 7, 5)) + bail("couldn't get movieinfo"); + movieinfo = *(struct movieinfo **)(instr + 2); + debug("movieinfo = %p", (void *)movieinfo); + } return true; } |