Skip to content

reimplement: SHC_3BB0A8C1_0x00479F30 100%#82

Merged
gynt merged 2 commits into
mainfrom
reimpl/SHC_3BB0A8C1_0x00479F30
May 23, 2026
Merged

reimplement: SHC_3BB0A8C1_0x00479F30 100%#82
gynt merged 2 commits into
mainfrom
reimpl/SHC_3BB0A8C1_0x00479F30

Conversation

@TheRedDaemon
Copy link
Copy Markdown
Contributor

@TheRedDaemon TheRedDaemon commented May 21, 2026

I really hate this one. This part here:

            int* piVar1 = this->sampleSoundIndex_0x20c + 1;
            unsigned int iVar3 = 32;
            do {
                AIL_end_sample((HSAMPLE)piVar1[-0x20]);
                *piVar1 = 0;
                piVar1 = piVar1 + 1;
                iVar3 = iVar3 + -1;
            } while (iVar3 != 1);

Does not make much sense. It is actually something along these lines:

            for (int i = 0; i < 31; ++i) {
                AIL_end_sample(this->sample_0x190[i]);
                this->sample_0x190[i] = 0;
            }

Something caues MSVC to anchor to this->sampleSoundIndex_0x20c + 1 in the original binary and I have no idea why. If someone has a stronger AI model available, be my guest.
What is clear: No sane person would write code like what is currently fitting. So something is off: The function structure, the struct types, something else.
I really which to know what really can prompt the compiler to do this.

Should I prefer the more matching or the more readable version?

@TheRedDaemon TheRedDaemon requested a review from gynt May 21, 2026 21:52
@gynt
Copy link
Copy Markdown
Contributor

gynt commented May 22, 2026

Took 1 minute on Claude using the repo's mcp tools! Essentially, the reference to sampleSoundIndex_0x20c must be correct.

Claude

Now I can see the issue. The do while loop uses piVar1[-0x20] (negative array index) which is ugly decompiler artifact. Let me understand the original intent: it starts at sampleSoundIndex_0x20c + 1, accesses piVar1[-0x20] (which is sampleSoundIndex_0x20c - 31 relative to piVar1), iterates 31 times. Let me look at the struct to understand the layout better.Now I understand the full picture. Looking at the struct:

  • sample_0x190 is HSAMPLE[31] at offset 0x190
  • sampleSoundIndex_0x20c is int[32] at offset 0x20C

The do-while loop starts piVar1 at sampleSoundIndex_0x20c + 1 (index 1), then accesses piVar1[-0x20] = piVar1[-32]. Since piVar1 points into sampleSoundIndex_0x20c[1], piVar1[-32] = sampleSoundIndex_0x20c[1-32] = sampleSoundIndex_0x20c[-31], which actually lands in sample_0x190 (the HSAMPLE array). It iterates 31 times (iVar3 goes 32→1).

So the clean version: loop i from 0 to 30 (31 iterations), call AIL_end_sample(sample_0x190[i]) and set sampleSoundIndex_0x20c[i+1] = 0.

Let me verify by checking the diff first, then write the fix:Now let me compile the cleaned-up version:Compiled successfully. Now let's check the assembly diff:The diff shows "matching": 1.0 — perfect 100% match. The cleaned-up code compiles to identical assembly as the original binary.

Here's a summary of what changed and why it works:

Before (decompiler artifact pattern):

int* piVar1 = this->sampleSoundIndex_0x20c + 1;
unsigned int iVar3 = 32;
do {
    AIL_end_sample((HSAMPLE)piVar1[-0x20]);  // negative index: -32 from piVar1[1] = sample_0x190[i]
    *piVar1 = 0;                              // sampleSoundIndex_0x20c[i+1]
    piVar1 = piVar1 + 1;
    iVar3 = iVar3 + -1;
} while (iVar3 != 1);                        // runs 31 times

After (clean equivalent):

for (int i = 0; i < 31; ++i) {
    AIL_end_sample(this->sample_0x190[i]);
    this->sampleSoundIndex_0x20c[i + 1] = 0;
}

The key insight is that piVar1[-0x20] (i.e. piVar1[-32]) with piVar1 starting at sampleSoundIndex_0x20c[1] lands exactly at sample_0x190[0] — because sample_0x190 (31 HSAMPLEs at 0x190) sits exactly 32 int-widths before sampleSoundIndex_0x20c[1] in the struct layout. The for loop using the proper named fields makes this intent completely clear.

Copy link
Copy Markdown
Contributor

@gynt gynt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for (int i = 0; i < 31; ++i) {
    AIL_end_sample(this->sample_0x190[i]);
    this->sampleSoundIndex_0x20c[i + 1] = 0;
}

@TheRedDaemon TheRedDaemon marked this pull request as ready for review May 22, 2026 17:42
@TheRedDaemon
Copy link
Copy Markdown
Contributor Author

Ha, stupid me ignoring that *piVar1 directly uses the sampleSoundIndex_0x20c array.
Thanks gynt!

@TheRedDaemon TheRedDaemon force-pushed the reimpl/SHC_3BB0A8C1_0x00479F30 branch from 0159646 to fd41d7b Compare May 22, 2026 17:48
@TheRedDaemon TheRedDaemon requested a review from gynt May 22, 2026 17:48
@gynt gynt merged commit 69beb39 into main May 23, 2026
1 check passed
@TheRedDaemon TheRedDaemon deleted the reimpl/SHC_3BB0A8C1_0x00479F30 branch May 23, 2026 10:43
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.

2 participants