Virtua Fighter 3 Recomp

Virtua Fighter 3 Recomp is a native PC port of Virtua Fighter 3 that supports higher resolutions, widescreen, and up to 120 frames per second.

README

Virtua Fighter 3 Recomp

Virtua Fighter 3 Recomp

Virtua Fighter 3 (SEGA, arcade, Model 3, 1996) as a native PC game: the game's own PowerPC program, recompiled to native code, with render scales up to 6x, widescreen and ultrawide, smooth motion up to 120 pictures a second and the 3D on the GPU.

Latest release Licence: MIT Platforms

Play · Download · Trailer · Status · Controls · Report a bug

Virtua Fighter 3 Recomp in widescreen at 3x with 2x antialiasing: fights on six stages

Watch the trailer
Trailer (click to watch on YouTube)

[!IMPORTANT] No game files are included: no ROMs and nothing made from them. You need your own dump of the game as MAME's vf3 set (vf3.zip, Revision D). It is read on your computer, and the game's program is recompiled there each time it starts. An unofficial fan project, not made, approved or supported by SEGA, and not affiliated with it.

About

Virtua Fighter 3 Recomp runs the game's own program, for the board's PowerPC 603e, recompiled to native code (ARM64 or x86-64) from your ROM each time it starts, and checked frame for frame against its own interpreter, which is itself frame-identical to the Supermodel reference on every scripted run (the attract mode, all twelve fighters, a versus match and the test menu: 173,000 frames). The rest of the Model 3 board is this port's own code: the board itself (memory map, IRQs, the 53C810 SCSI controller's DMA, the JTAG chain, EEPROM, inputs), the tile generator and the Real3D Pro-1000 (a scene builder and two renderers: on the CPU, and on the GPU with SDL_GPU, the same picture, checked against each other when the game starts); the sound board's 68000 and two SCSPs run on MAME's code as Virtua Fighter 2 Recomp has it. Supermodel's source, GPL, was read for its documentation of the hardware; none of its code is in this one.

Status

AreaState
The PowerPC program, recompiled to native codeWorking: identical to the interpreter on every frame checked
Board, tile generator, Real3D (CPU renderer)Working: the pictures match the reference's, but for the differences below
The 3D on the GPU (Display > 3D renderer: Auto, GPU or CPU)Working on Metal (Apple M4 Max: 120 pictures a second at 4x and 6x) and Vulkan (checked against the CPU's picture as the game starts); Direct3D 12 not yet tried on real hardware. Direct3D 12 that draws nothing falls back to Vulkan, and any difference or error to the CPU
Sound board (68000, two SCSPs)Working: against the reference's on the same inputs, the same loudness (0.1 dB apart on average) and balance across the bands, a little brighter above 8 kHz (MAME's SCSP, where the reference has its own)
Render scale up to 6x, antialiasing, widescreen and ultrawide, smooth motionWorking. Widescreen: the fights see more to the sides, and the stages' backgrounds carry on from the game's own panoramas
Menu, keyboard and gamepads, two players, the arcade's settings, screen filtersWorking
Portable mode, your own ROM folderWorking
macOS, Windows, Linux / Steam DeckmacOS (Apple silicon) and the Steam Deck: the downloads working, a steady 60 pictures a second on the Deck; Windows tested under Wine; Intel Macs not yet tried (the Mac build is universal)
Online playNot yet

This is an alpha. Please report anything that looks or plays differently from the arcade in Issues, with the log.txt from the game's data folder.

Known issues: Shun's stage water is the game's own low-resolution 2D art up close, and Direct3D 12 is untested. Virtua Fighter 3 Team Battle (vf3tb) isn't supported yet.

Known differences from the reference's pictures: textures far away are softer (the Real3D's own mipmap level choice, as Supermodel's New3D documents it, where the reference build used OpenGL's).

Play

SystemDownload
macOS 11+ (Apple silicon and Intel)VirtuaFighter3Recomp-mac.zip
Windows 10 or 11 (64-bit)VirtuaFighter3Recomp-windows.zip
Linux / Steam Deck (x86-64)VirtuaFighter3Recomp-deck.tar.gz

Mac and Windows

  1. Unzip it (Mac: move Virtua Fighter 3 Recomp to Applications; Windows: the VirtuaFighter3 folder anywhere, not inside Program Files).
  2. Open it (Windows: VirtuaFighter3.exe).
  3. Choose your vf3.zip when it asks. A copy is kept, so you only do this once.

Steam Deck

  1. Copy the download to the Deck (e.g. Downloads) and unpack it there: in Desktop Mode, right-click it in the file manager > Extract > Extract archive here. (Unpacking on Windows, or copying the folder through a USB stick, can lose the files' permissions, and then nothing launches.)
  2. Put your vf3.zip in the VirtuaFighter3/roms folder.
  3. Desktop Mode: Steam > Games > Add a Non-Steam Game to My Library > Browse, set the file type filter to "All files", pick the vf3 file in the VirtuaFighter3 folder, Add Selected Programs. In its Properties, set Start In to the VirtuaFighter3 folder (e.g. /home/deck/Downloads/VirtuaFighter3/), and under Compatibility leave "Force the use of a specific Steam Play compatibility tool" off: it's a native Linux game, and Proton stops it launching.
  4. Back in Game Mode, launch it from your Library with the default Gamepad layout.

The Windows download also runs on the Deck under Proton (add VirtuaFighter3.exe instead, with Proton forced on), but the native Linux build above is the one to use. The Deck package also keeps a copy of your vf3.zip in your user data folder, so an update unpacked into a new folder doesn't ask for it again.

On another x86-64 Linux PC: unpack it anywhere, put vf3.zip in its roms folder and run VirtuaFighter3.sh.

Portable mode: put a file named portable.txt next to the program (Windows: beside VirtuaFighter3.exe; Mac: beside the app, in the same folder), or in the folder above it, and the game keeps everything in that folder: settings, saves, screenshots, log.txt and the copy of your vf3.zip (in its roms folder), with nothing in your user data folder (%APPDATA%, ~/Library/Application Support). The Linux / Steam Deck build keeps everything in its folder already.

Your own ROM folder (e.g. Batocera's /userdata/roms/ports/vf3, or any folder an update won't touch): start the game with --roms <folder> (or --roms=<folder>), set the environment variable VF3_ROMS, or add roms_folder = <folder> to settings.ini; the command line wins, then VF3_ROMS, then settings.ini. ~ is your home folder, and a relative path in settings.ini is from its folder. The game looks there first for vf3.zip and only reads it (no copy is kept anywhere else); log.txt names the folder it used. If the zip isn't there, the log says where it looked and the game carries on as without the option; a zip you then choose with the file picker is copied into your ROM folder, so the next start finds it there. Examples: Windows VirtuaFighter3.exe --roms "D:\ROMs\vf3"; Mac open "Virtua Fighter 3 Recomp.app" --args --roms ~/ROMs/vf3; Linux / Batocera ./VirtuaFighter3.sh --roms /userdata/roms/ports/vf3.

[!NOTE] The Mac and Windows builds aren't signed. On macOS, open it once, close the message, then System Settings > Privacy & Security > Open Anyway. On Windows, if SmartScreen warns, choose More info > Run anyway.

Controls

Change them in the menu (Esc, or View / Select on a pad).

KeyDoes
↑ ↓ ← →Player 1: move
Z X C VPlayer 1: guard, punch, kick, escape
1Player 1: start
I J K LPlayer 2: move
B N M ,Player 2: guard, punch, kick, escape
2Player 2: start
5 6Coins (Arcade play style)
EscThe menu (a pad: View, L3 + R3, or the touchpad's click)
P / F3Pause / reset
F5 / F6Render scale / picture shape
F11, F or Alt+EnterFullscreen
F9The frame rate and timings in the title bar
F12A screenshot of the picture (in the Screenshots folder)
Tab (held)As fast as it goes
F2 / 9The arcade's test and service buttons (in its test menu, Down and Start do too)

Gamepads: d-pad or left stick, X guard, A punch, B kick, Y escape, LT guard + punch, RB punch + kick, LB guard + kick, RT all three, Start. The menu: View (tapped), L3 + R3, or the touchpad's click (View + Start too). View + LB: render scale; View + RB: picture shape. For Arcade play on a pad, set a Coin button in Controls.

Menu

  • Resume and Quit.
  • Display: render scale (up to 6x), antialiasing (2x, 3x), the 3D renderer, picture shape (fit the window, 4:3, 16:10, 16:9, 21:9), background filter, smooth motion, screen filter (scanlines, CRT), Show FPS, fullscreen.
  • Sound: volume, and the music's and the effects' own volumes.
  • Game: play style (PC: no boot screen, always free play; Arcade: the boot, coins and credits, its coin settings kept for it), reset.
  • Arcade settings: difficulty, rounds to win, energy, demo sound, country, and the arcade's own service menu (its other settings, sound test, bookkeeping). A change restarts the game.
  • Controls: each player's pad, keys and buttons.

If the computer can't keep up, the game first shows only the arcade's own 57.5 pictures a second, then lowers the antialiasing and the render scale, and lifts them again once it can.

How it works

The recompiler (src/rec) finds the PowerPC program's code with an address map (src/rec: where the functions start and where the indirect jumps lead, addresses only, no bytes from the ROM), made from coverage runs of the reference, and turns it into native code with SLJIT as the game starts; the interpreter (src/ppc) is kept for checking and for any code the map missed. Around it, this port's own code runs the rest of the Model 3 board (the memory map, IRQs, the SCSI controller's DMA, the tile generator, the Real3D's scene builder and its CPU rasteriser), and MAME's code the sound board's 68000 and SCSPs. The SDL 3 host puts the picture together, scales and shapes it, and fills in the pictures between the arcade's 57.5 frames a second for smooth motion, by blending the 3D models between frames.

The 3D can also be drawn on the GPU (src/gpu, SDL_GPU: Metal on a Mac, Direct3D 12 or Vulkan on Windows and Linux): the CPU's polygons, prepared as for its own rasteriser, are drawn by the GPU with the CPU's shading in the same layers and passes, put together with the 2D on the GPU and never read back. As the game starts it compares the GPU's picture of the game's own scene with the CPU's, and keeps the GPU only if they match; any error later, and it uses the CPU for that run. Auto (the default) uses the GPU once it has passed, unless the GPU is itself drawn by the CPU (a machine with no graphics driver), where the CPU's own renderer is faster.

Repository layout

PathContents
src/ppcthe PowerPC 603e interpreter
src/recthe recompiler (SLJIT) and the address map it starts from (addresses only)
src/corethe shim MAME's CPU cores and disassemblers compile against
src/machineModel 3 Step 1.0: memory map, IRQs, the 53C810's DMA, JTAG, EEPROM, inputs, the ROM set
src/videothe tile generator, the Real3D's scene builder, smooth motion's in-betweens and the CPU rasteriser
src/gputhe Real3D on the GPU (SDL_GPU), its HLSL shaders (r3d.hlsl) and their compiled forms (r3d_shaders.h)
src/soundthe sound board: MAME's SCSP and its DSP, with MAME's 68000 in third_party/mame
src/hostthe SDL 3 game: window, input, pacing, the GPU compositing, settings, the RmlUi menu
assets/the app icon, the menu (ui/) and its font
third_party/MAME's 68000 and SCSP, SLJIT, RmlUi (third_party/README.md)
tools/recompthe address map's maker (from coverage runs)
tools/refthe instrumented reference build (Supermodel with coverage, input scripts and state dumps)
tools/gpu/shaders.shcompiles r3d.hlsl into r3d_shaders.h (DXC and SPIRV-Cross)
tools/*.cpp, tools/*.pythe headless runner (vf3run), the lockstep checker (vf3lock), the state comparison
tools/mac, tools/win, tools/deck, tools/releasethe release packages and their licence notices
tools/sitethe download page

Run it yourself

Needs a C++20 compiler, zlib, SDL 3.4 and FreeType (Mac: brew install sdl3 freetype; Linux: from source or your distribution). The tools need only a C++20 compiler and zlib.

make                    # build/bin/vf3 (the game), vf3run and vf3lock (the tools)
build/bin/vf3 path/to/vf3.zip

The release packages: tools/mac/package.sh (Mac), tools/win/build.sh (Windows, cross-compiled with MinGW-w64), tools/deck/build.sh (Linux / Steam Deck: x86-64, in Valve's Steam Runtime container). tools/release/licenses.sh gathers the third-party notices they carry. The GPU's shaders are compiled into src/gpu/r3d_shaders.h (committed) by tools/gpu/shaders.sh.

  • vf3run <vf3.zip> --script FILE [--rec] [--state FILE] [--shots DIR] [--wav FILE]: the game headless, with an input script (the reference build's format, src/host/input_script.h), writing the CPU's state after every frame (for tools/statecmp.py), screenshots and the sound.
  • vf3lock <vf3.zip> --script FILE: the interpreter and the recompiled code side by side, compared after every frame.
  • tools/ref/: the instrumented reference build, run hidden. docs/ has each step's record.
  • The game itself: VF3_HIDDEN=1 VF3_QUIT_AFTER=N and the other VF3_* variables listed at the top of src/host/main.cpp.

How it's made

Made with the help of AI coding tools. Every build is checked: the recompiled PowerPC program runs side by side with the interpreter, which matches the Supermodel reference frame for frame, and the pictures and sound are compared with the reference's.

The whole story, with how the AI-assisted work was organised and checked: docs/HOW-IT-WAS-MADE.md.

Credits

Built on MAME's work: the 68000 core (Olivier Galibert), the SCSP and its DSP (ElSemi, R. Belmont) and the Model 3 sound board's design (R. Belmont, Ville Linde), as Virtua Fighter 2 Recomp has them (third_party/mame/README.md lists the files), all BSD-3-Clause. Supermodel (Bart Trzynadlowski, Ian Curtis, Nik Henson and others) was read as documentation of the Model 3 and its Real3D, and was the reference everything was checked against; none of its code is in this one. Also SLJIT (Zoltan Herczeg, BSD-2-Clause), RmlUi (MIT), SDL 3 (zlib), FreeType (FreeType License), zlib, and the Barlow Condensed font (SIL Open Font License).

Virtua Fighter 3 is SEGA's. This project is not affiliated with or endorsed by SEGA.

Licence

MIT for this project's own code: see LICENSE. Code from MAME keeps its BSD-3-Clause licence and notices; the rest of third_party/ keeps its own (third_party/README.md), and the Barlow Condensed font the SIL Open Font License. The app icon (assets/icon/, drawn by tools/release/make_icon.py) is by Mr Finster under CC BY 4.0.

Support

If you enjoy it, you can buy me a coffee.