Syphon Filter Omega Strain Decomp: The Licensed CodeWarrior Build That Made It Match
By Indie Kings | October 21, 2026
Updated October 21, 2026: The Syphon Filter: The Omega Strain decompilation for PlayStation 2 has 13,667 of 14,344 functions matching, which is 95.28% of the functions but 81.74% of the code by byte. The project's own progress log records that a clean build with a licensed CodeWarrior install reproduces the retail executable byte for byte.
Image: GitHub repository card for zm2283145/syphon-filter-omega-strain-decomp.
What the project is reconstructing
Per the repository README, this holds a matching decompilation of the PlayStation 2 executable SCUS_972.64, the NTSC-U release of Syphon Filter: The Omega Strain. The goal is C source that, built with the original compiler, reproduces the retail executable byte for byte.
No game data is stored in Git. The README says you need your own copy of the game, and that every file derived from it, including split assembly, objects and the rebuilt executable, is created locally in git-ignored folders.
GitHub reports 4 stars, no forks and 2 open issues for the repository, with 2 contributors. The lead contributor accounts for 203 commits, with the other at 43. The source tree holds 8,610 entries, of which 8,395 are files, with the source directory accounting for 8,217 entries, the headers for 320, the tooling for 24 and the tests for 7. The GitHub language breakdown puts C at 15,723,421 bytes, which is 97.5% of the 16,131,742 bytes in the project, with Python at 368,596 bytes and C++ at 39,246 bytes. GitHub reports no licence for the repository.
The size of that source directory, 8,217 entries, is the first thing to notice, and most of it is the game itself. Of the entries under the source directory, the main program accounts for 5,750, the data directory for 1,049 and the library directory for 1,418.
The match numbers and the two reports
The project publishes two different sets of numbers, and the difference between them is worth understanding before reading either.
| Measure | ByteMatch report | Project's own progress log |
|---|---|---|
| Functions matched | 13,667 of 14,344, which is 95.28% | 6,047 of 14,845, which is 40.73% |
| Code bytes matched | 2,992,396 of 3,661,084, which is 81.74% | 314,420 of 3,663,320, which is 8.58% |
| Units complete | 8,013 of 8,417 | Every matched C unit fully linked, at 8.58% of linked code |
| Data | 339,056 bytes matched, which is 99.85% | 339,552 bytes counted separately, not linked from C |
The gap is not a mistake, and the progress log explains it. The project's own report counts the functions it can claim with the compiler it is entitled to use, which for the archive builds of CodeWarrier is the 3.0.3 series, while the ByteMatch report counts everything the project has matched, including the batch of functions that only match under the licensed CodeWarrior 3.0 build 38 install. The log describes a clean full build with the per-unit choices as reproducing the retail executable byte for byte, and separately notes that the code progress just above 8 percent was reached with the licensed build.
Either way, the round-trip build is byte-identical. The progress log's state table records the round-trip build as byte-identical with SHA-256 9924da91767c8145411f37fa6c14c9d77208264c17f1ce9ee157d51abdd31dc6, on Windows with native tools.
The project also lists roughly 2,700 named functions in its symbol address file, and is listed on decomp.dev under its own project key.
The compiler problem at the centre of it
The most interesting section of the progress log is its first decision, and it is about the compiler rather than the game. The game code is Metrowerks CodeWarrior for PS2. The decomp.me archive builds that run without a FlexLM license reproduce small and straight-line functions, but they differ systematically from the retail code in instruction scheduling around calls and branch targets, with an extra no-operation before branch targets and after calls and different delay-slot filling.
That is the classic code-generation fingerprint problem, and the project's answer is to get the original toolchain. The owner-licensed CodeWarrior PS2 3.0 build 38 installation, built March 7, 2003, is now the primary game compiler for the units selected in the project's compiler overrides file, with CodeWarrior 3.04 build 22 retained for one static initializer. The log is careful about what that establishes: it says this establishes code-generation compatibility, not proof of the exact compiler used for every retail unit.
The toolchain table in the README lays out the whole stack. The game code is Metrowerks CodeWarrior for PS2 with the compiler flags -O4,p, and the original linker is mwldps2, which writes a comment string identifying MW MIPS C Compiler 2.4.1.01 into the output. The SDK and middleware are prebuilt Sony libraries, the graphics and pad libraries at SDK 2.8, along with Medius 1.50, lgaud and 989snd, built with EE-GCC.
For the decompilation itself the project uses splat for the split, GNU binutils for MIPS to assemble and link, and objdiff for the difference and progress reports. The compiler used in the build is mwcps2-3.0.3-020716 by default, with per-unit overrides for CodeWarrior PS2 3.0 build 38 and 3.04 build 22, and EE-GCC 2.95.3 and 2.96 for the library units.
The library work and the 7,873 unmatched functions
The most recent rounds have been on game and interface code rather than the library layer, with the October 21, 2026 commit reporting 16 more matched functions in a single round. An earlier batch added 56 EE-GCC library functions covering the C library, the SDK, MPEG and network helpers, plus one Metrowerks MPEG parser stub, with two build changes going with them: a Metrowerks unit starting on an 8-byte rather than 16-byte boundary now gets its text alignment from its retail address, and without a licensed override compiler the configure script now prints a warning and builds its assigned units from their retail assembly, so the licence-free build still matches, with those functions counting as unmatched in a local report.
There is also a scan in the log of the 7,873 unmatched functions outside the main code range, looking for toolchain fingerprints in what remains. It finds 573 that contain a single-precision compare, and the conclusion drawn is that this game code looks like 3.04 output while existing matches show some differences, so the two builds are being used per unit rather than globally.
That per-unit approach is visible throughout the recent entries. A batch of 24 functions covering local-player publication, GUI and menu helpers, lobby callbacks, destructors and initialization routines was made with 3.04 and has since been retested with the build 38 overrides, and all 24 are identical in objdiff. Other entries record routines that match build 38 and 3.04 but differ with the default 3.0.3, and the log notes that the clean whole build leaves every prior complete unit unchanged each time.
The trial runner and the integration rules
The project ships a runner that tries multiple compilers against a candidate function, and its design is the most careful thing in the repository. The default is a single serial trial against the default compiler and source profile, plans are limited to six trials unless the ceiling is explicitly raised, with a hard ceiling of 15 and a per-compiler timeout. Available profiles are source, no-peephole, no-common-subs, no-propagation and no-strength-reduction.
Two details in that runner matter. The profiles request compiler prefix pragmas, but source and header pragmas remain intact and may override them, so the runner warns that an effective per-function setting is not guaranteed. And the runner leaves sources unchanged, creating isolated scratch directories instead.
The README's rules for integrating a candidate are explicit. Pick a function from the split assembly, noting that functions must start on a 16-byte boundary and so must the next one because every object is 16-byte aligned. Insert a C subsegment and an assembly subsegment in the split configuration, write the source file, reconfigure and build, and let the SHA-256 check be the final word, using objdiff to find differences. Only commit functions that build byte-identically.
For parallel work the README asks for non-overlapping functions and isolated output and input snapshots, with shared configuration, whole builds and publication under one integrator. It also states that neither ranking nor compiler-trial output authorizes a match claim.
What the repository holds and what it does not
The rules section of the README is a list of what must never be committed: the executable, disc data, split assembly, objects, decompiler output and BIOS files, all covered by the ignore file. A match may only be claimed when the build's SHA-256 check passes.
The setup instructions are equally specific. You copy your own SCUS_972.64 from the root of your disc, or an image of it, into the project directory, and its SHA-256 must be the one given. The compiler is described as proprietary Metrowerks software archived by decomp.me, with the note that it should be downloaded only if you are entitled to use it and that it is never committed. The additional licensed builds are not included or downloaded by the setup script, and their directories are passed on the command line.
FAQ
Which version of Syphon Filter is being decompiled?
The PlayStation 2 executable SCUS_972.64, the NTSC-U release of Syphon Filter: The Omega Strain. The README says you supply your own copy from the root of the disc or an image of it, and the configure script checks its SHA-256 before doing anything else.
Why are there two different match percentages?
Because the progress log's status table is dated October 10, 2026 while the ByteMatch report is regenerated by CI on every push. The log's state table gives 6,047 of 14,845 functions and 8.58% of code bytes, and the current report gives 13,667 of 14,344 functions and 81.74% of bytes. The project also notes that its function totals shift as the splitting tool refines function boundaries, so the two can differ for reasons other than progress.
What does the licensed compiler change?
The build reproduces the retail executable byte for byte once the per-unit compiler choices are used, including the licensed build 38 as the primary game compiler with 3.04 build 22 retained for one static initializer. The progress log says this establishes code-generation compatibility, not proof of the exact compiler used for every retail unit.
Does the project include the game?
No. The README states no game data is stored in Git and that every file derived from the game is created locally in git-ignored folders. The rules section repeats that the executable, disc data, split assembly, objects, decompiler output and BIOS files must never be committed.
How is a match claimed?
By the build's SHA-256 check passing and the function being byte-identical. The README says only to commit functions that build byte-identically, and warns that neither the runner's ranking nor its compiler-trial output authorizes a match claim.
How do parallel contributors avoid collisions?
The README asks for non-overlapping functions and isolated output and input snapshots, with shared configuration, whole builds and publication kept under one integrator. Compatible candidates are batched into the final full-image check.
Bottom Line
Syphon Filter: The Omega Strain is decompiled well past the halfway mark by functions and to 81.74% of its code by byte, and the interesting part of the project is the compiler problem underneath it. The archive builds of CodeWarrior produce different instruction scheduling around calls and branch targets from the retail code, and the fix was to obtain the original licensed toolchain, CodeWarrior 3.0 build 38, and use it per unit rather than globally, with 3.04 retained for a single static initializer. The project is careful not to overclaim, noting that the result establishes code-generation compatibility rather than proof of the exact compiler for every unit. It is also candid in a second way, keeping an older status table in the progress log alongside the current CI figures without reconciling the two on the page. The engineering around it is unusually polished for a project of this size, with a bounded trial runner that leaves sources untouched, per-function pragmas it warns might not take effect, and a rule that the SHA-256 check is the final word. The work is two contributors and 305 commits, and the honest summary of the numbers is 95.28% of functions and 81.74% of bytes.
Sources
- zm2283145/syphon-filter-omega-strain-decomp repository README, PROGRESS.md, DECOMP_DEV.md and the linked handoff document, accessed October 21, 2026
- Repository metadata, language breakdown, contributor list and commit history via the GitHub API, accessed October 21, 2026
- ByteMatch report for zm2283145/syphon-filter-omega-strain-decomp, accessed October 21, 2026
Related: 24,515 Functions Later: The 3.3.5a Client Is 90 Percent Decompiled | ShadPS4 - The Future of PS4 Emulation | 7 Unofficial PC Ports Worth Knowing in September 2026 [2026]