Getting Started with CNA

CNA — C++ XNA 4.0 reimplementation  ·  Work in progress

CNA is a work in progress. XNA API coverage is partial and growing. It is suitable for experimentation and engine research — not for shipping production games at this stage.

What you are getting

CNA is a C++ framework that mirrors the XNA 4.0 programming model. You write game code against the Microsoft::Xna::Framework C++ API. CNA handles windowing, input, audio, and rendering through SDL3 and a pluggable backend system.

If you have XNA or MonoGame experience, the patterns will feel familiar. The main difference is C++ instead of C#.

Prerequisites

Linux

  • CMake 3.20 or newer
  • C++23-capable compiler: GCC 12+ or Clang 15+
  • ../sharp-runtime directory (sibling to the CNA repo) — no external dependencies
  • ../easy-gl directory — only needed for the EASYGL backend
  • SDL3, SDL3_image, and SDL3_mixer are built from vendored submodules — no system packages required

Windows

  • CMake 3.20 or newer
  • One of: MSVC 2022 (v17.8+), clang-cl, or MinGW-w64
  • ..\sharp-runtime directory (sibling to the CNA repo)
  • SDL3 built from vendored submodules — no pre-built binaries or CMAKE_PREFIX_PATH needed

Clone & initialise

git clone https://github.com/openeggbert/cna.git
cd cna
git submodule update --init --recursive

This populates third_party/SDL, third_party/SDL_image, and third_party/SDL_mixer. After this step no system SDL packages are required.

Quick start build (Linux — EasyGL backend)

git submodule update --init --recursive
cmake -S . -B build -DCNA_GRAPHICS_BACKEND=EASYGL
cmake --build build --target CNA CnaTests
ctest --test-dir build --output-on-failure

Quick start build (Linux — SDL_Renderer backend)

cmake -S . -B build-sdlrenderer -DCNA_GRAPHICS_BACKEND=SDL_RENDERER
cmake --build build-sdlrenderer --target CNA CnaTests

Verify the build

# Run the test suite
ctest --test-dir build --output-on-failure

# Run the hello-triangle verification demo
cmake --build build --target hello-triangle-sdl

Minimal game skeleton

Here is the smallest possible CNA game — a window that clears to cornflower blue, the traditional XNA default clear colour.

#include <memory>

#include "Microsoft/Xna/Framework/Game.hpp"
#include "Microsoft/Xna/Framework/Color.hpp"
#include "Microsoft/Xna/Framework/Graphics/GraphicsDeviceManager.hpp"
#include "Microsoft/Xna/Framework/Graphics/SpriteBatch.hpp"
#include "Microsoft/Xna/Framework/Graphics/Texture2D.hpp"

using namespace Microsoft::Xna::Framework;
using namespace Microsoft::Xna::Framework::Graphics;

class MyGame final : public Game {
public:
    MyGame() : graphics_(this) {}

protected:
    void LoadContent() override {
        spriteBatch_ = std::make_unique<SpriteBatch>(getGraphicsDeviceProperty());
        logo_ = std::make_unique<Texture2D>("assets/logo.png", getGraphicsDeviceProperty());
    }

    void Update(GameTime& gameTime) override {
        (void)gameTime;
        // Update game state here.
    }

    void Draw(const GameTime& gameTime) override {
        (void)gameTime;
        auto& device = getGraphicsDeviceProperty();
        device.Clear(CornflowerBlue);
        spriteBatch_->Begin();
        spriteBatch_->Draw(*logo_, 100.0f, 80.0f);
        spriteBatch_->End();
        device.Present();
    }

private:
    GraphicsDeviceManager graphics_;
    std::unique_ptr<SpriteBatch> spriteBatch_;
    std::unique_ptr<Texture2D> logo_;
};

int main() {
    MyGame game;
    game.Run();
    return 0;
}

Next steps

External references

CNA targets the XNA 4.0 API surface. These references document the target API: