Skip to content

vpinball/pinmame-dotnet

Repository files navigation

PinMAME for .NET

CI status (x64 Linux, Android, iOS, macOS and Windows) NuGet

Add PinMAME support to any .NET application

This NuGet package provides a .NET binding for PinMAME, an emulator for solid state pinball machines. It uses the cross-platform LibPinMAME.

This package is built from the pinmame git submodule and automatically published on each push to master.

Supported Platforms

  • .NET Core (.NETStandard 2.1 and higher on Windows, Linux and macOS)
  • Mono

Setup

The native wrapper is a different package and contains pre-compiled binaries of LibPinMAME.

NuGet Package
Windows 64-bit PinMame.Native.win-x64-badge
Windows 32-bit PinMame.Native.win-x86-badge
macOS x64 PinMame.Native.osx-x64-badge
macOS arm64 PinMame.Native.osx-arm64-badge
macOS x64/arm64 PinMame.Native.osx-badge
iOS arm64 PinMame.Native.ios-arm64-badge
Linux x64 PinMame.Native.linux-x64-badge
Android arm64-v8a PinMame.Native.android-arm64-v8a-badge

To install this package with the native dependency of your current platform, run:

Install-Package PinMame
Install-Package PinMame-Native

Usage

Create a PinMame instance, and then start a game.

using PinMame;
var _pinMame = PinMame.PinMame.Instance();

_pinMame.StartGame("t2_l8");

You can add event handlers for:

  • OnGameStarted
  • OnDisplayAvailable
  • OnDisplayUpdated
  • OnAudioAvailable
  • OnAudioUpdated
  • OnMechAvailable
  • OnMechUpdated
  • OnSolenoidUpdated
  • OnConsoleDataUpdated
  • OnGameEnded
  • IsKeyPressed

To process display data, in your OnDisplayUpdated callback:

void OnDisplayUpdated(int index, IntPtr framePtr, PinMameDisplayLayout displayLayout) 
{
    if (displayLayout.IsDmd)
    {
        // Handle DMD displays (framePtr is byte*)
    }
    else
    {
        // Handle Alphanumeric displays (framePtr is ushort*)
    }
};

To add or update a mech:

_pinMame.SetHandleMechanics(0);

PinMameMechConfig mechConfig = new PinMameMechConfig(
   (uint)(PinMameMechFlag.NonLinear | PinMameMechFlag.Reverse | PinMameMechFlag.OneSol),
   11,
   240,
   240,
   0,
   0,
   0);
mechConfig.AddSwitch(new PinMameMechSwitchConfig(33, 0, 5));
mechConfig.AddSwitch(new PinMameMechSwitchConfig(32, 98, 105));

_pinMame.SetMech(0, mechConfig);

To remove a mech:

_pinMame.SetMech(0, null);

See the example project for more information.

Versioning

This project maintains two separate versions:

1. PinMAME Native Version

Defined in Directory.Build.props as PinMameNativeVersion (e.g., 3.7.0)

  • Used for native DLL naming: libpinmame.3.7.0.dylib, libpinmame.so.3.7.0
  • Update this when updating the pinmame submodule to a new upstream release

2. PinMameDotNet Version (git tag-based)

Automatically calculated from git tags:

  • Release (tag pushed): git tag v0.3.0 && git push origin v0.3.0

    • Builds as 0.3.0 and publishes to NuGet
  • Development builds (commits after tag):

    • 1st commit after v0.3.00.3.1.0
    • 2nd commit after v0.3.00.3.1.1
    • 3rd commit after v0.3.00.3.1.2
    • etc.
  • Next release: git tag v0.4.0 && git push origin v0.4.0

    • Builds as 0.4.0 and publishes to NuGet
    • Cycle repeats: 0.4.1.0, 0.4.1.1, etc.

Publishing: Only releases (tagged versions) are published to NuGet automatically. Development builds are built and tested but not published.

Native vs .NET Package Versions

  • Native packages (PinMame.Native.*) are versioned with PinMameNativeVersion (e.g., 3.7.0-beta1)

    • Only republished when the native version changes in Directory.Build.props
    • Skipped if that native version already exists on NuGet
  • .NET wrapper (PinMame) is versioned with git tags (e.g., 0.3.0)

    • Has a dependency on the corresponding native package version
    • Published on every tagged release

This means you can release new .NET wrapper versions without rebuilding/republishing unchanged native libraries.

Building from Source

This repository uses a git submodule for the PinMAME source. To clone and build:

# Clone with submodules
git clone --recursive https://github.com/vpinball/pinmame-dotnet.git

# Or if you already cloned without --recursive
git submodule update --init --recursive

The GitHub Actions workflow build-and-publish.yml builds libpinmame for all platforms and creates NuGet packages. To build locally:

# Build libpinmame for your platform
cd pinmame
cp cmake/libpinmame/CMakeLists.txt .
cmake -DPLATFORM=<platform> -DARCH=<arch> -DCMAKE_BUILD_TYPE=Release -B build
cmake --build build

# Build the .NET wrapper
cd ../src/PinMame.Tests
dotnet build -c Release -r <rid>
dotnet test -r <rid>

Where <platform> is one of: win, macos, linux, android, ios And <rid> is one of: win-x64, win-x86, osx-x64, osx-arm64, linux-x64, android-arm64-v8a, ios-arm64

License

MAME/BSD-3-Clause

About

Cross-platform PinMAME-binding for .NET

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages