Skip to content

Building the Core ​

The emulator core is located in the VCCore directory of the repository. It is a plain C++20 library with a CMake build. The macOS application uses the same sources through the Xcode project.

Requirements ​

  • A C++20 compiler: GCC, Clang, or Visual Studio (MSVC)
  • CMake

If CMake finds zlib, the core is built with support for compressed files (gzip). Without zlib, the build still succeeds and the compressed formats are unavailable.

Targets ​

VCCore/CMakeLists.txt defines two targets and pulls in the libraries they depend on:

TargetDescription
VCCoreThe emulator core as a library. It links the utility library utlib, the retro vault library rvlib, and the SID emulation resid.
VC64HeadlessA small command-line app performing smoke tests (see Headless App).

With no build type set, CMake builds the Release configuration.

Building on Linux and macOS ​

Configure, build, and run the self tests from the root of the repository:

cpp
cmake -B build -S VCCore
cmake --build build
ctest --test-dir build --verbose

To build a Debug version, pass -DCMAKE_BUILD_TYPE=Debug to the first command. To choose a compiler, pass -DCMAKE_CXX_COMPILER=clang++ (or g++) and the matching -DCMAKE_C_COMPILER.

Building on Windows ​

With Visual Studio, use the compiler detected by CMake and select the configuration when building:

cpp
cmake -B build -S VCCore
cmake --build build --config Release
ctest --test-dir build --build-config Release --verbose

With MinGW (MSYS2), use the Ninja generator:

cpp
cmake -G Ninja -B build -S VCCore -DCMAKE_BUILD_TYPE=Release
cmake --build build

The headless app additionally links ws2_32 on Windows. CMake takes care of that.

Self tests ​

ctest runs the headless app three times:

TestCommandWhat it does
SelfTest1VC64Headless --verbose --footprintReports the size of the core objects.
SelfTest2VC64Headless --verbose --smokeRuns a RetroShell script that exercises the emulator.
SelfTest3VC64Headless --verbose --diagnoseLaunches the emulator thread and runs the self-diagnosis script.

The same three commands run on every push on GitHub, for Linux (GCC and Clang), Windows (MSVC), and MinGW, each in the Release and Debug configuration.

Using the core in your project ​

The easiest way to use the core is to add it as a subdirectory of your own CMake project:

cpp
add_subdirectory(path/to/VCCore)
add_executable(myapp main.cpp)
target_link_libraries(myapp VCCore)

Linking VCCore brings in the other libraries and adds the VCCore directory to the include path, so the API header is found with:

cpp
#include "VirtualC64.h"

The class vc64::VirtualC64 is the entry point of the API. The following program creates an emulator instance, configures it, and runs it. The emulator computes frames in a thread of its own, so the main thread is free to do other work.

cpp
#include "VirtualC64.h"

using namespace vc64;

// Receives all messages sent by the emulator. Note that the function is
// called on the emulator thread.
static void process(const void *listener, Message msg, std::exception_ptr error)
{
    // Forward the message to the user thread (not shown)
}

int main()
{
    // Create an emulator instance
    VirtualC64 c64;

    // Launch the emulator thread
    c64.launch(nullptr, process);

    // Install the ROMs. Here, we use the MEGA65 OpenROMs.
    c64.c64.installOpenRoms();

    // Configure the emulator
    c64.set(Opt::VICII_REVISION, long(VICIIRev::PAL_6569_R3));

    // Start the emulator
    c64.run();

    // Interact with the emulator, e.g., by typing a string
    c64.keyboard.autoType("LOAD \"*\",8,1\n");

    // ...
}

The chapter Headless App shows a complete program that is used for smoke tests.