Languages like C#, VB.NET, C++/CLI, and F# compile to a binary instruction set called CIL. CIL binaries are platform-independent, but can only be executed on platforms with a CIL VM, (such as the .NET runtime). SwitchPalace is a set of tools for transforming CIL binaries into other formats so they may be used without runtime dependencies.
The primary tool in SwitchPalace is a translator that converts a CIL binary into platform-specific code. Users may select between generating a platform-specific executable (e.g. a win32 PE file) or generating C code that can be passed to a platform-specific compiler. In all cases, the resulting output has no dependencies on a VM or any non-system libraries.
Although converting directly to a platform-specific binary is simplest, the optimizing compiler in SwitchPalace is far inferior to optimizers in common C compilers, so using C as an intermediary produces the most performant results. Thankfully, because the generated C has no dependencies on non-system libraries, compiling the C code for the target platform is trivial.
The final version of SwitchPalace understands the instruction set used by version 2.0 of the common language runtime, supporting inputs that target .NET 1.0 through 3.5. Output can be generated to target the following platforms:
In addition to the cross-compilation tool, SwitchPalace includes API bindings for common system services, allowing generated output to make use of audio, graphics, network, and filesystem resources on each supported platform.
Not all platforms share comparable hardware-accelerated graphics, so a CPU-based graphics interface is included in the API bindings. The following sample tests how many animated sprites can be rendered atop an animated background using only CPU-based composition.
This benchmark is fun to run on recent hardware, as modern machines can draw well over 100,000 sprites at 60fps using only a single thread of the CPU (i.e. by simply looping over each pixel of a sprite and copying it to the screen buffer if it's not transparent).
The SpriteTest was used to measure performance on both home computer and mobile device. The most recent devices at the time of writing produced the following results:
|Device||Platform||CPU||Sprites @ 60 FPS|
|Laptop - 2011||Mac||2.2 GHz Core i7 (Sandy Bridge Mobile)||110,000|
|Laptop - 2011||Windows||2.0 GHz Core i7 (Sandy Bridge Mobile)||100,000|
|Laptop - 2011||Managed||2.0 GHz Core i7 (Sandy Bridge Mobile)||74,000|
|BlackBerry Z10 - 2013||BlackBerry||1.5 GHz ARM Cortex A15 (MSM8960)||26,000|
|BlackBerry PlayBook - 2011||BlackBerry||1.0 GHz ARM Cortex A9 (OMAP4430)||11,000|
|Samsung Galaxy S1 - 2010||Android||1.0 GHz ARM Cortex A8 (Exynos 3)||8,700|
Converting an assembly to a native executable is simple:
switchpalace myapplication.exe win32 myapplication_native.exe
Source generation is accomplished in a similar manner:
switchpalace myapplication.exe win32 myapplication_native.c
SwitchPalace can be used to convert code written in any language that compiles to the Common Intermediate Language (e.g. C#, VB.NET). No special tools are needed during development; conversion operates on the final binary that results from development. Programs to be converted with SwitchPalace may reference the SwitchPalace standard library assembly, which exposes the APIs available on every target platform.
At conversion time, the SwitchPalace standard library assembly is replaced with a platform-specific module that implements the standard library functionality for the target platform. Implementations for each target are provided in both binary and source forms for inclusion in executable and source output modes respectively.
I implemented a few goofy little demo effects to exercise the API during development. The following samples generate procedural graphics while rendering MOD files to the audio buffer: