Running On Other OSs - dekay/vpinball-wiki GitHub Wiki
Running Visual Pinball on Other Operating Systems
Thanks to the hard work of many talented developers, Visual Pinball is now a (mostly) cross-platform application. It was initially developed in a branch known as "Standalone", referring to the fact that it does not have the Table Editor or Preferences GUI that the Windows version has. For some more background on how the Standalone branch came to be, check out the Readme file for VPinball Standalone, written by its main developer @jsm174.
Besides Windows, VPinball now runs on
- Linux x64 (more here)
- macOS, both ARM and x64 (more here)
- iOS (more here)
- Android, both ARM and legacy ARM (more here)
- Raspberry Pi 64bit (more here)
TODO Distinguish between officially and unofficially supported versions.
Prior to the 10.8 release, new Standalone features first appeared in its own branch of the code and were regularly merged into the main code base. Now, most of the new development for Standalone happens in VPinball's "master" branch, and you can see the latest changes here.
TODO Create a feature table of the different versions
Installation
The cross-platform versions became part of VPinball's official releases as of Version 10.8. You can find those releases here on Github Scroll down a bit to the Assets section, where you might need to click on "Show all xx assets" to see the version for you.
If you are feeling like running more on the cutting edge, new releases are generated on every commit to the Master branch of the code. To get to those, go to project's Github Actions page, click on a recent commit, and scroll down a bit to find the latest release resulting from that commit.
[!NOTE] You will need to be logged into Github to access these builds
[!NOTE] A new build may not be created for a given commit for every platform if the change does not impact that platform. Try a few different ones if need be.
If you wish, you can also compile the code from source. Instructions for doing so for any of its supported platforms are on Github.
Joystick Configuration
Visual Pinball Standalone uses SDL Game Controller mappings instead of SDL Joystick mappings. To set up your controller, add an entry to the gamecontrollerdb.txt
file. You can find mappings for many popular controllers in the SDL Game Controller Database.
Once you've updated gamecontrollerdb.txt
, adjust the corresponding entries in VPinballX.ini
for your controller. Here's an example configuration for an Xbox controller:
Button | Action | Key = Value |
---|---|---|
Left Shoulder | Left Flipper | JoyLFlipKey = 10 |
Right Shoulder | Right Flipper | JoyRFlipKey = 11 |
Left Stick | Left Magna Save | JoyLMagnaSave = 8 |
Right Stick | Right Magna Save | JoyRMagnaSave = 9 |
D-pad Up | Center Tilt | JoyCTiltKey = 12 |
D-pad Left | Left Tilt | JoyLTiltKey = 14 |
D-pad Right | Right Tilt | JoyRTiltKey = 15 |
D-pad Down | Plunger | JoyPlungerKey = 13 |
A | Add Credit | JoyAddCreditKey = 1 |
B | Start | JoyStartGameKey = 2 |
X | FPS | JoyFrameCount = 3 |
Y | Cancel | JoyPMCancel = 4 |
Guide | Fire | JoyLockbarKey = 6 |
Note: Game controller button indexes in VPinballX.ini
are 1-based, meaning they start from 1 instead of 0.
Keyboard Configuration
If you want to customize the keyboard input, update the ; Keyboard input mappings
section in the VPinballX.ini
file. The settings are decimal values based on DirectInput DIK_
values found here.
Key | Value | Notes |
---|---|---|
ESCAPE | 1 | |
1 | 2 | |
2 | 3 | |
3 | 4 | |
4 | 5 | |
5 | 6 | |
6 | 7 | |
7 | 8 | |
8 | 9 | |
9 | 10 | |
0 | 11 | |
MINUS | 12 | - on main keyboard |
EQUALS | 13 | |
BACK | 14 | Backspace |
TAB | 15 | |
Q | 16 | |
W | 17 | |
E | 18 | |
R | 19 | |
T | 20 | |
Y | 21 | |
U | 22 | |
I | 23 | |
O | 24 | |
P | 25 | |
LBRACKET | 26 | |
RBRACKET | 27 | |
RETURN | 28 | Enter on main keyboard |
LCONTROL | 29 | |
A | 30 | |
S | 31 | |
D | 32 | |
F | 33 | |
G | 34 | |
H | 35 | |
J | 36 | |
K | 37 | |
L | 38 | |
SEMICOLON | 39 | |
APOSTROPHE | 40 | |
GRAVE | 41 | |
LSHIFT | 42 | |
BACKSLASH | 43 | |
Z | 44 | |
X | 45 | |
C | 46 | |
V | 47 | |
B | 48 | |
N | 49 | |
M | 50 | |
COMMA | 51 | |
PERIOD | 52 | . on main keyboard |
SLASH | 53 | / on main keyboard |
RSHIFT | 54 | |
MULTIPLY | 55 | * on numeric keypad |
LMENU | 56 | Left Alt |
SPACE | 57 | |
CAPITAL | 58 | |
F1 | 59 | |
F2 | 60 | |
F3 | 61 | |
F4 | 62 | |
F5 | 63 | |
F6 | 64 | |
F7 | 65 | |
F8 | 66 | |
F9 | 67 | |
F10 | 68 | |
NUMLOCK | 69 | |
SCROLL | 70 | Scroll Lock |
NUMPAD7 | 71 | |
NUMPAD8 | 72 | |
NUMPAD9 | 73 | |
SUBTRACT | 74 | - on numeric keypad |
NUMPAD4 | 75 | |
NUMPAD5 | 76 | |
NUMPAD6 | 77 | |
ADD | 78 | + on numeric keypad |
NUMPAD1 | 79 | |
NUMPAD2 | 80 | |
NUMPAD3 | 81 | |
NUMPAD0 | 82 | |
DECIMAL | 83 | . on numeric keypad |
F11 | 87 | |
F12 | 88 | |
F13 | 100 | |
F14 | 101 | |
F15 | 102 | |
NUMPADEQUALS | 141 | = on numeric keypad |
AT | 145 | |
COLON | 146 | |
UNDERLINE | 147 | |
STOP | 149 | |
NUMPADENTER | 156 | Enter on numeric keypad |
RCONTROL | 157 | |
NUMPADCOMMA | 179 | , on numeric keypad |
DIVIDE | 181 | / on numeric keypad |
RMENU | 184 | Right Alt |
PAUSE | 197 | Pause |
HOME | 199 | Home on arrow keypad |
UP | 200 | Up Arrow on arrow keypad |
PRIOR | 201 | Page Up on arrow keypad |
LEFT | 203 | Left Arrow on arrow keypad |
RIGHT | 205 | Right Arrow on arrow keypad |
END | 207 | End on arrow keypad |
DOWN | 208 | Down Arrow on arrow keypad |
NEXT | 209 | Page Down on arrow keypad |
INSERT | 210 | Insert on arrow keypad |
DELETE | 211 | Delete on arrow keypad |
LWIN | 219 | Left Windows |
RWIN | 220 | Right Windows |
Tools
A number of tools and fixes have been developed by the Visual Pinball community to help make life easier for those running on other platforms. Here are a few.
- vpxtool is something of a terminal-based Swiss Army knife for Visual Pinball. Written by @francisdb, it's features include:
- commands that let you work with VPinball's
.vpx
format (list the files it contains, tell you what ROMs the table might require, extract the Visual Basic table script from the file, etc) - tools to help automatically patch a file to work around bugs in the winescript engine that the Standalone version depends on to run the table's coded in Visual Basic
- a text-based frontend for launching tables
- commands that let you work with VPinball's
- DMD Config by @Le-Syl21 is a tool to analyze DirectB2S FullDMD files and automatically generate DMD (Dot Matrix Display) placement configurations for your virtual pinball cabinet.
- VPX GUI Tools for Linux by @surtarso is a GUI tool for launching VPX tables, editing the settings in the
VPinballX.ini
file, extracting VBS scripts and more with "just a mouse click". It has its own wiki where you can learn a lot more. - VPX Settings Editor by @herrMirto is a settings GUI that aims to more closely mimic the configuration GUI from the Windows version. The author also plans to implement a window positioning assistant to help with the on-screen arrangement of the many windows (playfield, DMD, backglass, PuP, etc) that VPX is capable of generating.
- VPX Standalone Scripts is a set of table patches to work around bugs in the winescript engine mentioned above that are triggered by the Visual Basic code in some tables. There are very few non-PUP tables that won't run on the Standalone version of Visual Pinball, either out of the box with one of these patches.
- Visual Pinball L3SP4UL Settings is a collection of settings for over 200 (!) tables painstakingly created by Discord's @L3SP4UL that strives for the ideal Point-Of-View and perfect scaling settings for the mobile versions of Visual Pinball.
Where To Go For Help
Probably the best place to get help is on the Virtual Pinball Discord. Start by looking in the vpx-standalone channel for PC or the vpx-standalone-mobile channel for iOS and Android.
How Visual Pinball Standalone Works
[!TIP] This section is for those curious as to how a Windows-native program got ported over to run on non-Windows platforms. You don't need to know any of this if you just want to play pinball :-)
Visual Pinball was built over 20 years ago using Microsoft technologies such as OLE Compound Documents, DirectX, VBScript, COM, and ATL -- many of which have no cross platform equivalents or support. A common misconception is that VPX Standalone runs under Wine. In fact, it only uses just enough of Wine's source code for things like the VBScript engine. More on this below.
To make a successful port, a number of different challenges had to be overcome:
OLE Compound Documents
- Visual Pinball Table (
.vpx
) files are stored in Compound File Binary Format.Solution
- Implement POLE - portable library for structured storage to load
.vpx
files.- Create
PoleStorage
wrapper to matchIStorage
interface.- Create
PoleStream
wrapper to matchIStream
interface.
Windows Registry
- Visual Pinball stores and retrieves its settings from the Windows registry.
Solution
- Use the
ENABLE_INI
preprocessor definition which uses RapidXML to save and retrieve settings from a file instead. Note that as of VPX 10.8, the Windows version now uses this same approach instead of the registry.
VBScript
- Visual Pinball uses VBScript as the scripting engine for tables.
Solution
- Leverage the VBScript engine from Wine.
- Fix bugs in Wine's VBScript engine. The bugs that affect VPinball and the workarounds for them are tracked here. VPinball Standalone syncs with Wine's upstream code as fixes are made. Standalone also carries its own workarounds for some bugs that are not yet fixed upstream.
- Add support for
Scripting.FileSystemObject
andScripting.Dictionary
leveraging Wine'sscrrun
code.- Add support for
E_NOTIMPL
commands to Wine's VBScript engine:
Execute
ExecuteGlobal
Eval
GetRef
COM / ATL
- Visual Pinball uses COM as a bridge between the scripting engine and itself. The scripting engine uses COM to access other components such as VPinMAME and B2S.Server.
- Visual Pinball uses ATL to dispatch events from itself to the scripting engine, ex:
DISPID_GameEvents_Init
andDISPID_HitEvents_Hit
Solution
- Leverage just enough Wine source code to set up the platform to match Windows, ex:
wchar_t
is 2 bytes in Windows while 4 bytes on most other platforms. (_WINE_UNICODE_NATIVE_
)- Provide stubs for as much COM and ATL code as possible by using Wine and ReactOS source code.
- Embed Wine's VBScript engine instead of trying to replicate Windows RPC.
- Replace Windows
typelib
magic with class methods forGetIDsOfNames
,Invoke
,FireDispID
, andGetDocumentation
- Create two
idlparser
utilities that read Interface Definition File and automatically generates C and C++ code forGetIDsOfNames
,Invoke
,FireDispID
, andGetDocumentation
- Embed
libpinmame
to provide support for PinMAME based games
Graphics
- Visual Pinball uses either DirectX or OpenGL for graphics.
Original Solution
- Use OpenGL (version 4.6 on Linux and version 4.1 on MacOS). Android, iOS, tvOS, Raspberry PI, and RK3588 use OpenGLES 3.0.
Current Solution
- Take advantage of VPX 10.8's move to the cross-platform, graphics API agnostic BGFX rendering library. This allows VPX to take advantage of each platform's preferred high performance graphics API: DirectX on Windows, Vulkan on Linux, Metal on macOS and iOS, etc.
Sound
- Visual Pinball uses DirectSound for playing
.wav
files and BASS for playing all other audio files.Original Solution
- Use the
ONLY_USE_BASS
preprocessor definition which uses BASS for all audio files including.wav
files.Current Solution
- Port the codebase to use SDL3 Audio and SDL Mixer instead. This brought with it Surround Sound Feedback support to non-Windows platforms.
Input
- Visual Pinball uses XInput and either DirectInput 8 or SDL2 for getting keyboard and joystick info.
Solution
- Make a
SDLK_TO_DIK
translation table that converts SDL Keys to DirectInput Keys.- Add additional support for
SDL_KEYUP
andSDL_KEYDOWN
events.
Updating
- The Visual Pinball repository is constantly updated with new features and bug fixes.
Solution
Updates must be easy to rebase, so all changes must be wrapped in:
#ifdef __STANDALONE__ #endif
or
#ifndef __STANDALONE__ #else #endif
Note that as of the 10.8.1 version of VPX, most new development of Standalone now occurs in VPinball's master branch. However, these wrappers are still required for platform-dependent code.