Skip to content

[saco] implement/match some func on saco - #20

Open
ricardoofnl wants to merge 310 commits into
dashr9230:mainfrom
ricardoofnl:main
Open

[saco] implement/match some func on saco#20
ricardoofnl wants to merge 310 commits into
dashr9230:mainfrom
ricardoofnl:main

Conversation

@ricardoofnl

@ricardoofnl ricardoofnl commented Jul 19, 2026

Copy link
Copy Markdown

No description provided.

@ricardoofnl ricardoofnl changed the title [saco] implement/match cmdprocs.cpp command handlers [saco] implement/match some func on saco Aug 1, 2026
@ricardoofnl

Copy link
Copy Markdown
Author

heads up on a wall i hit doing CAudioStream in saco, documenting it in case anyone knows the trick

CAudioStream::Stop at .text:10066560 has a spin wait, while(byte_1012E7B8) Sleep(2);, and the retail dll compiles it as a non inverted test at top loop

push    esi
mov     esi, ds:__imp__Sleep@4
lea     esp, [esp+0]
loc_10066590:
mov     al, byte_1012E7B8
test    al, al
jz      short loc_1006659F
push    2
call    esi
jmp     short loc_10066590
loc_1006659F:
pop     esi

every cl 13.10 i throw at it rotates that into a do/while (or a guard plus do/while when the flag is volatile), which is 2 bytes shorter so it never lines up

push    2
call    esi
mov     al, byte_1012E7B8
test    al, al
jne     short loc_10066590

i figured it was a compiler micro version thing so i parsed the rich header of samp.dll, the C++ backend objects sit at build 3077 (188 objs), 4035 (2 objs) and 3052 (1 obj), so i pulled all three and tested each on this exact loop, 3077 from vs.net 2003 rtm, 3052 from the free vc toolkit 2003, 4035 from the windows server 2003 sp1 ddk, and all three emit the identical rotated do/while, none give the retail shape. 4035 is byte for byte identical to 3077 on the four CAudioStream funcs i already matched so the build number is not the thing here

what fits this, every func matched so far has no while loop (Reset, ControlGameRadio, Play have none, DrawInfo and ConstructInfo only have do/while char scans), Stop is the only real while and the only one that refuses. i went through around 25 source and structure forms (plain while, while(1) with break, do { if(!f) break; } while(1), an explicit goto test at top cfg, the early return as goto vs || vs two ifs, volatile vs not, the flag as BYTE/char/bool/int, Sleep in the condition via comma, /Os, /G5//G6//G7) and nothing reproduces it, so it reads like a lost toolchain nuance rather than something expressible in source with the three compilers that actually built the dll

CAudioStream::Process at .text:10066700 is the stream thread body with the same kind of spin loop so it is stuck for the same reason

CAudioStream::Play at .text:10066960 is a knock on effect, it is fully reversed and byte matches, but it calls Stop and i cannot land it clean yet, with Stop as a return 0 stub the compiler proves it pure and drops the call inside Play (dead call elimination, and __declspec(noinline) does not help since it is purity not inlining), so Play only matches once Stop has a real body with side effects

anyone seen retail saco built with a cl outside those three builds, or a pragma around the wait loops? otherwise i will park Stop/Process/Play and keep grinding the stubs that do not hit a spin loop

stubs for reference Stop Process Play

…dex the object pool, offsets clamped to +/-100
…s; the aliases were declared but never defined
…te loads `ecx`, so 0x100A0210 is the member
…nd it at both map-icon call sites instead
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant