Native32 is a game format developed by Sunplus for DVD player and TV chipsets (circa 2005–2011). Games use .smf, .sgm, or .ssl file extensions and feature a stack-based, ActionScript-like virtual machine with raster graphics.
- Full Native32 format support — file loading, header decryption, resource table parsing
- YUV & ARGB image decoding — with packbits/RLE decompression and color space conversion
- Action bytecode VM — 36 opcodes covering arithmetic, logic, string ops, control flow, sprites, and I/O
- Sprite/movie system — animation, cloning, visibility control, depth-sorted rendering
- Audio playback — MP3 music and raw 16-bit PCM sound effects
- MPEG-1 cutscenes — pure-Rust MPEG-1 video + MP2 audio decoder plays
SSL_PlayNextlogo/cutscene videos (no C dependency); skippable with A/B - ZIP archive support — load game packages directly from
.zipfiles (auto-extracts and loads FHUI.smf) - Keyboard input — configurable key remapping
- Save system —
.ssl_savfile persistence - SSL multi-file content — seamless switching between game levels/files
- CLI controls — scaling, fullscreen, volume adjustment
- RetroArch integration — libretro core for use with RetroArch frontend
Download the latest binary from the Releases page.
The basic usage is listed below, but there are many more options for controlling the behavior of the emulator. See the Command-line Options documentation for the full list of options.
# Basic usage
native32-emu path/to/game.smf
# Load from ZIP archive (auto-extracts and loads FHUI.smf)
native32-emu path/to/game.zip
# Fullscreen mode
native32-emu --fullscreen game.smfZIP mode: When loading from a .zip file, the emulator starts the FHUI
menu. Selecting a game launches it; pressing ESC during gameplay returns to
the menu. Pressing ESC on the menu itself exits the emulator. When loading a
.smf file directly, ESC exits as usual.
Native32Emu can be used as a libretro core with RetroArch, allowing you to play Native32 games with RetroArch's features like shaders, netplay, and achievements.
- Download the libretro core from the Releases page
- Install the core:
- Copy
native32emu_libretro.dll(or.so/.dylib) to RetroArch'scores/directory - Copy
native32emu_libretro.infoto RetroArch'sinfo/directory
- Copy
- Load the core in RetroArch:
- Open RetroArch
- Select "Load Core" → "Native32 (Native32Emu)"
- Select "Load Content" and choose a
.smf,.sgm,.ssl, or.zipgame file
The libretro core also runs on Android and can be reused by most Android RetroArch-based frontends. See Android Libretro Core for install and build instructions.
- ✅ Video output (XRGB8888 pixel format)
- ✅ Audio output (RAW PCM, stereo)
- ✅ Input handling (D-Pad + A/B buttons)
- ✅ Game loading (.smf, .sgm, .ssl, .zip files)
⚠️ MP3 audio (not yet implemented — only RAW PCM works)- ❌ Save states (not yet implemented)
- ✅ Core options (audio volume, key auto-repeat timing, swap A/B, auto-skip cutscenes)
Configurable from RetroArch's Quick Menu → Core Options (audio volume, key auto-repeat timing, swap A/B, auto-skip cutscenes). See Core Options for the full list.
| RetroPad Button | Native32 Keycode | Action |
|---|---|---|
| D-Pad Left | 0x0200 | Left |
| D-Pad Right | 0x0400 | Right |
| D-Pad Up | 0x1c00 | Up |
| D-Pad Down | 0x1e00 | Down |
| A (SNES East) | 0x8800 | B / Menu |
| B (SNES South) | 0x4000 | A |
- RAW PCM: Fully supported (11025Hz for YUV games, 22050Hz for ARGB games)
- MP3: Not yet supported in libretro mode (games using MP3 will have no music)
- Audio is output as stereo (mono sources are duplicated to both channels)
Requires Rust (stable).
cargo build -p native32emu --release
cargo run -p native32emu --release -- path/to/game.smf
cargo run -p native32emu --release -- -f path/to/game.smfThe binary is produced at target/release/native32-emu.
cargo build -p native32emu-libretro --releaseCargo names the cdylib after its lib target, so this produces native32emu.dll
on Windows (libnative32emu.so on Linux, libnative32emu.dylib on macOS) under
target/release/. RetroArch expects the core file to be named
native32emu_libretro.<ext>, so rename it accordingly before dropping it into
RetroArch's cores/ directory.
For Android cross-compilation, see Android Libretro Core.
Run the unit tests:
cargo test --workspaceThere is also a smoke test that loads every available game, runs it for a number
of frames, and checks that the emulator neither panics nor produces a blank
frame. It needs the (non-distributed) game assets, so it is #[ignore]d by
default and run on demand:
# Uses <repo>/tmp/native32_game by default, or set NATIVE32_GAME_DIR
cargo test -p native32emu-core --test smoke -- --ignored --nocapturecrates/
├── native32emu-core/ # Platform-independent emulator engine (library)
│ └── src/
│ ├── lib.rs # Crate root (module declarations)
│ ├── emulator.rs # Shared Emulator + VmHost (both front-ends)
│ ├── actions.rs # Action opcode enum (36 opcodes)
│ ├── action_vm.rs # Stack-based virtual machine
│ ├── audio_engine.rs # MP3/PCM audio (rodio for standalone, buffer for libretro)
│ ├── content_loader.rs # SSL multi-file content switching
│ ├── dat_loader.rs # .dat metadata / thumbnail decoder (front-end menu)
│ ├── des_constants.rs # DES permutation tables and S-boxes
│ ├── error.rs # Error types
│ ├── file_browser.rs # FHUI front-end game-list directory enumeration
│ ├── file_loader.rs # File I/O, header parsing, resource tables
│ ├── frame_player.rs # Main timeline frame playback (30fps)
│ ├── header_decryptor.rs # Custom DES ECB header decryption
│ ├── image_decoder.rs # YUV 4:2:0 and ARGB1555 image decoders
│ ├── input_handler.rs # Input to keycode mapping (keyboard / RetroPad)
│ ├── renderer.rs # Frame rendering with depth sorting
│ ├── save_manager.rs # Save data persistence (.ssl_sav)
│ └── sprite_system.rs # Movie/sprite instance management
├── native32emu/ # Standalone binary (-> native32-emu)
│ └── src/
│ ├── main.rs # Window loop and thin front-end
│ └── standalone/
│ ├── cli.rs # Command-line argument parsing
│ └── gamepad_overlay.rs # On-screen virtual gamepad overlay
└── native32emu-libretro/ # libretro cdylib (-> native32emu_libretro.{dll,so,dylib})
├── native32emu_libretro.info # RetroArch core metadata
└── src/
├── lib.rs # cdylib crate root
└── libretro/
├── api.rs # Exported libretro functions (retro_init, retro_run, etc.)
├── callbacks.rs # Callback management for video/audio/input
├── constants.rs # libretro constants
├── logger.rs # Bridges the `log` crate to the libretro log interface
└── types.rs # libretro type definitions
Game resources can be downloaded from Baidu Netdisk.
All 84 Native32 games in the test suite load and run without fatal errors.
| Category | Count | Status |
|---|---|---|
| Main Menu | 1 | ✅ Pass |
| EACT (Action) | 11 | ✅ Pass |
| EELA (Educational) | 32 | ✅ Pass |
| EPOP (Hot/Featured) | 9 | ✅ Pass |
| EPUZ (Puzzle) | 24 | ✅ Pass |
| ESPG (Sport) | 3 | ✅ Pass |
| ETAB (Chess/Board) | 4 | ✅ Pass |
| Total | 84 | ✅ All Passed |
For detailed game list with screenshots and descriptions, see Game Compatibility.
Contributions are welcome! Whether you're interested in fixing bugs, adding features, improving documentation, or testing game compatibility, we'd love your help. See CONTRIBUTING.md for details.
- n32emu by Myrtle Shah — an earlier and simple Python implementation
- BootlegGames Wiki — hardware documentation and game catalog
This project is licensed under the BSD 3-Clause License.