From 983d0be5920f43b281154a167693ceaad86d8da4 Mon Sep 17 00:00:00 2001 From: Matthew Wozniak Date: Sat, 16 Nov 2024 22:39:29 -0500 Subject: add 5288 support --- api.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) (limited to 'api.c') diff --git a/api.c b/api.c index f2be734..5ac08ee 100644 --- a/api.c +++ b/api.c @@ -33,6 +33,7 @@ struct audio_device **audio_device = 0; struct soundstate *snd = 0; void (*snd_recordbuffer)(void) = 0; void (*cbuf_addtext)(char *) = 0; +bool steampipe = false; // This macro is Copyright 2024 Michael Smith under the same license as above. #define NEXT_INSN(p, tgt) do { \ @@ -46,7 +47,8 @@ void (*cbuf_addtext)(char *) = 0; // TODO: should this be split up? -bool api_init(void) { +bool api_init(bool _steampipe) { + steampipe = _steampipe; void *engine_dll = os_dlhandle("engine"); createinterface_func engine_factory = (createinterface_func)os_dlsym(engine_dll, "CreateInterface"); @@ -81,13 +83,13 @@ bool api_init(void) { if (!cbuf_addtext) bail("couldn't find cbuf_addtext"); // find demoplayer - instr = (const u8 *)engclient->vt->is_playing_demo; + instr = steampipe ? (const u8 *)engclient->vt->steampipe_is_playing_demo : + (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 @@ -105,7 +107,6 @@ bool api_init(void) { } NEXT_INSN(p, "videomode"); } - debug("videomode = %p", (void *)videomode); // find cl_movieinfo { @@ -129,7 +130,6 @@ bool api_init(void) { 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); } // find SND_RecordBuffer... this is something! @@ -138,15 +138,22 @@ bool api_init(void) { struct concommand *snd_restart = cvar->vt->find_command(cvar, "snd_restart"); instr = (const u8 *)snd_restart->callback; void *s_init = 0; - // S_Init is the 3rd call in Snd_Restart_f + // S_Init is called after setting snd_firsttime to true. Look for the + // second call after the mov + bool snd_firsttime_set = false; int call_count = 0; - for (const u8 *p = instr; p - instr < 64;) { - if (*p == X86_CALL && ++call_count == 3) + for (const u8 *p = instr; p - instr < 80;) { + // mov byte ptr [snd_firsttime], 1 + if (p[0] == X86_MOVMI8 && p[1] == 0x05 && p[6] == 1) + snd_firsttime_set = true; + if (p[0] == X86_CALL && snd_firsttime_set && ++call_count == 2) { s_init = (void *)(p + 5 + *(i32 *)(p + 1)); + break; + } NEXT_INSN(p, "S_Init"); } - debug("S_Init = %p", (void *)s_init); - if (!s_init) bail("couldn't find S_Init"); + if (!s_init) + bail("couldn't find S_Init"); // step 2: find g_AudioDevice in S_Init // g_AudioDevice is the first variable assignment after the check for // the -nosound command line arg. look for that. @@ -162,8 +169,8 @@ bool api_init(void) { } NEXT_INSN(p, "g_AudioDevice"); } - debug("g_AudioDevice = %p", (void *)audio_device); - if (!audio_device) bail("couldn't get ptr to g_AudioDevice"); + if (!audio_device) + bail("couldn't get ptr to g_AudioDevice"); } return true; } @@ -172,8 +179,9 @@ bool api_find_snd_recordbuffer(void) { // continuation, we must do this part later // step 3: Find S_TransferStereo16 in CAudioDirectSound::TransferSamples void *transferstereo16 = 0; - const u8 *instr = (*audio_device)->vt->transfer_samples; - debug("CAudioDirectSound::TransferSamples = %p", (void *)instr); + const u8 *instr = steampipe ? + (*audio_device)->vt->steampipe_transfer_samples : + (*audio_device)->vt->transfer_samples; // S_TransferStereo16 is the 8th call in TransferSamples int call_count = 0; for (const u8 *p = instr; p - instr < 384 /* big func! */;) { @@ -183,7 +191,6 @@ bool api_find_snd_recordbuffer(void) { } if (!transferstereo16) bail("couldn't find transferstereo16"); - debug("S_TransferStereo16 = %p", transferstereo16); // step 4: find SND_RecordBuffer in S_TransferStereo16 // it should be the next call after an 'add ecx, ecx' // We are also going to get Snd_WriteLinearBlastStereo16 to get some other @@ -208,8 +215,6 @@ bool api_find_snd_recordbuffer(void) { } if (!snd_recordbuffer) bail("couldn't find snd_recordbuffer"); - debug("SND_RecordBuffer = %p", (void *)snd_recordbuffer); - debug("Snd_WriteLinearBlastStereo16 + 3 = %p", (void *)snd); return true; } -- cgit v1.2.3-54-g00ecf