TheLogicMaster / switch-gdx

A LibGDX Nintendo Switch Homebrew and Xbox/UWP backend
GNU General Public License v2.0
83 stars 9 forks source link
cplusplus game-development homebrew java libgdx nintendo-switch uwp xbox

SwitchGDX

Release

About

This is a Nintendo Switch Homebrew and Xbox UWP backend for the LibGDX game framework. It uses the Clearwing VM project to transpile Java to C++ along with custom native bindings for LibGDX. It supports Nintendo Switch Homebrew builds using LibNX, and Xbox/Windows Store with UWP. See the SwitchGDX thread on the LibGDX Discord server for support.

Pixel Wheels and Shattered Pixel Dungeon Ports Pixel Wheels Shattered Pixel Dungeon

Features

Compatibility

The majority of LibGDX is fully supported. A few features such as GL30 and audio recording are currently unsupported.

Extensions

FreeType, Controllers, and Box2D are supported. Bullet may be supported in the future.

JVM Languages

Since Clearwing takes Bytecode as an input, it can support any JVM language. The main limitation would be the Clearwing runtime library, which is limited and may not support all required functionality, though this can typically be easily added as needed. Java and Kotlin have been tested and work.

Libraries

Pure Java libraries should work without any extra work, assuming they don't use unsupported runtime library features or JNI. Libraries compiled with a JDK version greater than 8 could also pose an issue. If a library uses JNI, custom native bindings could be provided and things should just work, the shared library loading API has no effect. See Libraries for a list of tested libraries.

Ports

These are some LibGDX games that have been ported using SwitchGDX.

Todo

Limitations

See the Clearwing documentation for the limitations inherent to the "VM"

Installation

In addition to the C++ dependencies, JDK 16 is required. Rsync is used for incremental compilation, and CMake is used for building the generated C++ project.

Linux

Windows

UWP

Project Setup

For reference, there's an example project provided with the needed Gradle config to build a SwitchGDX project. If you are creating a new LibGDX project, there's a fork of the project builder, gdx-liftoff, with the SwitchGDX backend here. Just enable the Switch backend, and it will take care of the rest. To add SwitchGDX to an existing project, a new Gradle subproject needs to be created, adding the switch directory with the icon, switch.json config file, build.gradle file, and the actual src directory with the SwitchLauncher source class. The module needs to be added to settings.gradle, and the clearwingVersion and switchGdxVersion properties need to be set in either gradle.properties or the top level build.gradle, depending on the project layout. The switch build.gradle can be mostly copy-pasted, changing only the title and author variables and the asset copy paths, if not in core/assets. Any source paths to be used with the jnigen style native code inlining also needs to be added to the transpiler arguments in switch/build.gradle. As far as libraries are concerned, if they require using GDX reflection, then those classes need to be added to the switch.json reflective class pattern list. The list of verified libraries details the needed config entries. To enable the Ryujinx emulator, download/install it then set ryujinxPath in the local.properties file (Create if needed). Make sure Java Home points to Java 16 or select a Java 16 JDK as the Gradle JDK in Intellij build settings. Ensure that the project itself compiles with the Java 8 language level.

Usage

All the main tasks are present in the switchgdx Gradle group in the switch submodule. The first time transpiling will be quite long, but subsequent runs will be comparatively snappy. Incremental compilation is achieved here by transpiling into one directory then using rsync to only copy the changed files into the final C++ project directory.

Deploying to Switch

Ensure that the Homebrew Launcher is opened to the NetLoader before running the deploy task. By default, it tries pinging the Switch to find it, but manually specifying the IP in the nxlink command may be necessary depending on the network.

UWP

The UWP task opens Visual Studio, where the project settings need to be adjusted for the signing certificate and remote deployment options for running on an Xbox console in devkit mode. Running a debug build should be as simple as building the project and running it. There's a bug where the UWP project needs to be manually rebuilt to for the assets to be copied over into the UWP build directory. The first time the task is run will be quite slow, as it needs to install the VCPKG dependencies into <home_dir>/.SwitchGDX. If this first task gets interrupted before finishing, deleting the vcpkg directory and trying again may be necessary. Currently, for Release builds to link successfully, the debug runtime library (/MDd) needs to be used.

Debugging

The project can be debugged as a normal C++ project with your IDE of choice. CLion works out of the box with the CMake project. Simply run one of the Gradle tasks to transpile the project, then open the <project>/switch/build/<project> directory with CLion as a CMake project. A Run configuration should be automatically created. Set the working directory in the run config to the switch/build/<project> project directory so that assets can be properly loaded at runtime. To trace back a native crash, simply press the debug icon next to the run configuration, and it should jump right to the exception and show the native stack trace. By inspecting the generated code and call stack, null fields can be found and traced back to Java source code by looking at the vm::setLineNumber line numbers. Code changes may lead to additional classes being included by the transpiler, in which case the CLion CMake project needs to be reloaded using Tools/Cmake/Reload CMake Project or it won't compile. If using Windows, the devkitPro MinGW toolchain has to be selected under the project build settings. To debug a Java Exception being thrown, setting a breakpoint at the throw statement can be quite useful. If it's a place you can't easily add print-lines like a library, printf combined with vm::getNativeString can also be helpful to print out a Java string, potentially obtained from Object#toString. In CLion, vm::getNativeString can also be evaluated while debugging, which is often extremely useful for dynamically inspecting values without recompiling.

Windows

On Windows, if you change the working directory in CLion, it doesn't seem to find the required shared libraries, so manually copying the DLLs from C:\devkitPro\msys2\mingw64\bin into the executable directory may be necessary. Adding the directory to the Path doesn't seem to be sufficient.

Test Suite

The tests module is for running the GDX test suite and verifying GDX functionality. See Tests for working features. Building the test module requires building the tests module JAR in the libgdx repo and putting it in tests/libs, in addition to the lwjgl3 test module JAR for the required assets. The tests module is disabled if the tests/libs directory doesn't exist to not break JitPack builds and such.

Notes