aboutsummaryrefslogtreecommitdiff
path: root/api.c
diff options
context:
space:
mode:
Diffstat (limited to 'api.c')
-rw-r--r--api.c39
1 files changed, 22 insertions, 17 deletions
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;
}