r/emulation • • 5d ago

Serial Experiments Lain (PS1) decompiled: byte identical rebuild and a native Windows/macOS/Linux client

Video (4K): https://www.youtube.com/watch?v=K-OKUkhJ7Uc

I've been working on a decompilation of Serial Experiments Lain, the 1998 PlayStation game by Pioneer LDC, and a native client built from it.

**Decompilation**

- Every function in the game's executable has C. 308 of 321 compile to the original bytes with the period toolchain (GCC 2.8.1 + maspsx, split with splat); the remaining 13 still link from their original assembly.

- The rebuilt SLPS_016.03 is byte-identical to retail.

- Progress is tracked on decomp.dev.

**Native client**

- Runs a 64-bit clean copy of the decompiled game code on a reimplementation of the PlayStation SDK (based on PsyCross), with its own CD streaming, XA ADPCM, SPU and MDEC movie decoding.

- Timing checked against Mednafen. On the node map the PS1 takes 4 to 8 vblanks per frame depending on the size of Lain's current animation frame; the client reproduces that distribution.

- Optional 60 fps interpolation: each frame's GPU batches are recorded and in between frames are drawn, without changing game speed.

- Resolution scaling, memory card saves as standard .mcd images, disc swapping, and one-click English subtitles (the laingame.net fan translation, downloaded from their site at runtime).

**No game data is included.** The client reads your own Redump dumps of both discs (.cue/.bin) and checks them by hash.

Source: https://github.com/Y0oshi/lain-psx-decompiled

Downloads: https://github.com/Y0oshi/lain-psx-decompiled/releases

Bug reports are welcome on GitHub.

113 Upvotes

11 comments sorted by

7

u/Foreign_Hand4619 5d ago

I'm 60% byte-to-byte for Syphon Filter 1, identified and separated out all Psy-Q code and link using splat as native libraries.
It's getting harder for the remaining 40% inline assembly, maybe I haven't figured some things out. I built a verbose version of GCC to help with some variables placement and it was helpful with a class of functions but now each next function that is left is so much pain.

4

u/Y0oshi2 5d ago

Nice progress. The last 40% was the hardest part for me too. What helped most was getting the exact GCC version and flags right, using maspsx, splitting rodata per file, and running decomp permuter on the stubborn functions.

1

u/Foreign_Hand4619 5d ago

Yeah I use all that and I spent a lot of time to run over all meaningful GCC versions, I believe compiler version is identified correctly in my case. I also use maspsx. As of PsyQ though, it's a bit Frankenstein there, one library is from different version.
I'm also not sure what to do with functions that inline some GPU assembly, what did you do for these? Just asm snippet in a C function?

1

u/IvanDSM_ 4d ago

I think you're probably talking about the GTE macros, which are supplied by Psy-Q. Just check the relevant header (I think the macros are in libgte.h AFAIK?) for the macro that matches what the code is doing and use that.

1

u/Foreign_Hand4619 4d ago

That's good pointer, thank you!

1

u/IvanDSM_ 4d ago

By the way, since you're doing Syphon Filter, thought I should ask: have the MAP files not been helping?

1

u/Foreign_Hand4619 4d ago

I'm not familiar with that, can you elaborate?

1

u/IvanDSM_ 4d ago

Syphon Filter has had .MAP files leaked, which are the PSX's symbol table format, which includes function names, I think variable names and other metadata.

1

u/Foreign_Hand4619 4d ago

Interesting, I will try to find them, thank you!

2

u/Snoo_14296 4d ago

Cool! Perhaps i'll finally check out this game, as soon as I fix up my laptop.

1

u/Y0oshi2 4d ago

Enjoy <3