Porting 3D Movie Maker to Linux – A Journey from 1995 Code to Modern Multiplatform Fun
#Dev

Porting 3D Movie Maker to Linux – A Journey from 1995 Code to Modern Multiplatform Fun

Tech Essays Reporter
8 min read

After Microsoft released the original 3D Movie Maker source under MIT, Ben Stone created the 3DMMEx fork and, together with Mark Cave‑Ayland, removed legacy assembly, replaced Win32 with SDL, and de‑compiled a static audio library, culminating in the first native Linux build of the classic multimedia authoring tool.

Porting 3D Movie Maker to Linux

May 9 2026 – Ben Stone
Software Development


Microsoft’s 3D Movie Maker (codenamed Socrates) was a beloved, if quirky, multimedia authoring tool released in 1995. For three decades it lived solely inside Windows, its source code locked away in a corporate vault. In May 2022 Microsoft surprised the community by publishing the full source on GitHub under an MIT license, a move that made a historic piece of software finally accessible to anyone willing to dig into its internals.

Ben Stone’s fork, 3DMMEx, set out to do more than just compile the original code on a modern Windows toolchain. Its long‑term ambition was portability, and after 18 months of incremental work the project reached a milestone: a native Linux build that runs the original 1995 movies unchanged. This article walks through the technical obstacles that had to be cleared, the strategies used to overcome them, and what the achievement means for preservation of legacy multimedia software.


Why the Source Release Matters

The GitHub repository contains not only the application itself but also the Kauai framework (shared with Creative Writer 2), a custom scripting compiler, documentation, and a set of pre‑rendered assets. The code is surprisingly clean for its era—consistent style, abundant comments, and defensive assert statements. Those qualities made the codebase a rare example of 1990s engineering that could actually be understood and modernised.

“The 3DMM codebase is a lot cleaner than some other mid‑90s game source code releases I have seen.” – Ben Stone

Because the original developers could not push patches after shipping, they had to get the code right the first time. That discipline translates into a solid foundation for a port, but also means the code assumes a very specific build environment: Microsoft Visual C++ 5.0, 32‑bit Windows, and a handful of hand‑optimised assembly routines.


Major Porting Challenges

Issue Why it mattered How it was solved
Pre‑standard C++ dialect The code used Microsoft‑specific extensions that modern compilers reject. Replaced non‑standard constructs with standard C++11/14 equivalents and added #ifdef guards where necessary.
Kauai’s dual‑platform design Officially supports only Windows and Macintosh 68K; the Macintosh path is incomplete, and many calls bypass the abstraction layer to invoke Win32 directly. Abstracted the offending calls behind a thin SDL‑based layer, keeping the original Win32 implementation for Windows builds.
Inline x86 assembly Performance‑critical functions (memory copy, bitmap manipulation, custom compression) were written in hand‑rolled assembly, preventing compilation on non‑x86 targets. Switched the build to use the portable C++ implementations already present in the source; removed the #define that selected the assembly path. Minor bugs uncovered in the C++ versions were fixed, yielding a small performance gain on modern CPUs.
Pointer‑size assumptions The code assumed 32‑bit pointers, causing compile‑time errors on 64‑bit targets. Added static asserts around file‑format structures, introduced uintptr_t‑based types, and verified that on‑disk formats remain unchanged.
Static libraries (BRender, AudioMan) Both were shipped as pre‑compiled Windows x86 binaries, making them unusable on Linux or on 64‑bit Windows. BRender’s assembly was already replaced by portable C code by a previous contributor. AudioMan was reverse‑engineered with Ghidra; only the essential playback and conversion functions were de‑compiled to C++. The new module uses miniaudio for cross‑platform sound output and recording.
Lack of tests Without automated tests, regressions slipped in unnoticed during the extensive rewrites. Ported the few existing Kauai unit tests to Google Test, integrated them into the CMake build, and added new tests for the SDL backend and audio layer.

Replacing Win32 with SDL

The most visible change was swapping the Win32 GUI layer for SDL2, a widely‑used cross‑platform multimedia library. The process unfolded in stages:

  1. Proof‑of‑concept – A tiny "Hello World" Kauai application was built using SDL to verify event dispatch and basic rendering. This isolated the GUI work from the rest of the code.
  2. Graphics abstraction – Kauai’s GNV (Graphics Environment) and GPT (Graphics Port) classes already encapsulated drawing primitives. Their Win32 GDI calls were replaced with SDL equivalents (SDL_RenderCopy, SDL_SetRenderDrawColor, etc.).
  3. Font handling – Windows provided EnumFonts and CreateFontIndirect. SDL lacks a native font enumeration API, so a platform‑specific routine was added that scans common font directories (/usr/share/fonts, ~/.local/share/fonts) and builds a lookup table. The rendering itself uses SDL_ttf.
  4. Keyboard accelerators – Win32’s accelerator tables were reimplemented as a simple map from SDL_Keycode to command identifiers, making future custom keybinding support straightforward.
  5. Unicode handling – The original code stored strings in the system code page (CP1252). SDL expects UTF‑8, so conversion helpers (MultiByteToWideChar → UTF‑8) were added. This solved a lingering issue where an em‑dash appeared as a box in the UI.

Porting 3D Movie Maker to Linux - Ben Stone Online

The transition required many lines of glue code—what was a single Win32 call often became a handful of SDL calls—but the result is a clean separation that lets the same codebase compile for Windows, Linux, and eventually macOS.


De‑compiling AudioMan and Adding miniaudio

AudioMan was a static library (AUDIOD.LIB) that handled playback, recording, and format conversion. It was tightly coupled to the Windows multimedia API and COM, making a direct port impractical. Ben used Ghidra on a debug build that still contained symbol information. By focusing on the subset of functions required for 3DMM (WAV playback, ADPCM conversion), he produced a small C++ re‑implementation that compiles on any platform.

For the Linux side, the project now links against miniaudio, a single‑header library that abstracts ALSA, PulseAudio, and CoreAudio. This not only restored sound on Linux but also gave the application the ability to record audio through the same API, fulfilling a feature that was previously missing on non‑Windows builds.


Improving Debugging and Testing

Porting a 30‑year‑old codebase without a test suite is a high‑risk endeavour. Ben introduced several quality‑of‑life improvements:

  • Google Test integration – All existing Kauai unit tests were migrated, and new tests were added for the SDL backend and audio module.
  • NatVis visualisers – Custom visualisers for Visual Studio make the original Hungarian‑style types (e.g., STN) display their actual string contents instead of raw pointers. This dramatically speeds up debugging on Windows.
  • Static asserts on file‑format structs – Guarantees that structures used for movie serialization retain their exact size across 32‑ and 64‑bit builds.
  • Verbose script logging – Since UI logic lives in the embedded scripting language, additional logs now emit the currently executing script name and line number, helping developers trace UI glitches.

Porting 3D Movie Maker to Linux - Ben Stone Online

These steps not only prevented regressions during the port but also laid the groundwork for future contributors to add features without breaking compatibility with movies created three decades ago.


The Linux Build and What Lies Ahead

With the assembly stripped, SDL in place, and audio re‑implemented, Mark Cave‑Ayland took charge of the Linux‑specific glue code. He tackled case‑sensitive filename handling, POSIX path conventions, and integrated FluidSynth for MIDI playback and GStreamer for cutscene video. After a few months of iteration, the first successful native Linux launch was achieved.

Porting 3D Movie Maker to Linux - Ben Stone Online

The current state of 3DMMEx on Linux includes:

  • Full movie editing, rendering, and playback.
  • Audio recording and playback via miniaudio.
  • MIDI support through FluidSynth.
  • Video cutscene playback via GStreamer.

Remaining work focuses on input handling (mouse dragging still misbehaves on certain devices) and extending the port to other platforms such as macOS and WebAssembly (Emscripten). The project also aims to migrate all internal string handling to UTF‑8, which will require a careful redesign of the movie file format.


Implications for Software Preservation

Porting a legacy multimedia authoring tool to a modern, open‑source stack does more than give hobbyists a nostalgic playground. It demonstrates a reproducible workflow for rescuing other abandoned applications:

  1. Source release + permissive license provides the legal foundation.
  2. Replacing platform‑specific glue (Win32, Mac Toolbox) with a portable abstraction layer (SDL) creates a single code path for many OSes.
  3. Eliminating assembly removes the most stubborn barrier to cross‑compilation.
  4. Re‑implementing static libraries via de‑compilation or clean‑room re‑writes ensures the build can target any architecture.
  5. Adding tests and modern debugging aids safeguards future contributions.

The 3DMMEx story is a template for how developers can breathe new life into software that would otherwise be lost to obsolete hardware and closed ecosystems.


Getting Started

  • Source code: https://github.com/benstone/3dmmex
  • Linux build instructions: see the README.md in the repo; a typical build is mkdir build && cd build && cmake .. && make.
  • Pre‑built Windows binaries: available on the GitHub Releases page for x86, x64, and ARM64.
  • Further reading: Mark’s blog series on the Linux port (link in the repo) and the original Hanselminutes podcast discussing the source release.

If you are interested in contributing—whether by fixing mouse handling, adding macOS support, or experimenting with a WebAssembly build—check the GitHub issues and discussions pages. The community is small but enthusiastic, and each contribution helps preserve a piece of digital history.


Enjoy making animated movies on Linux, and may your scripts run without a single assert failure.

Featured image

Comments

Loading comments...