Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/HarbourMasters/Starship/llms.txt

Use this file to discover all available pages before exploring further.

The GameEngine class is the central runtime object for Starship. It owns the libultraship context, drives the audio and graphics pipelines, and exposes a dual-language surface — a static C++ class for engine code and a flat C API (extern "C") for logic that runs in the original ported C translation units. Both surfaces are declared in src/port/Engine.h.

SF64Version Enum

Before calling any version-gated API, use the SF64Version enum to identify which ROM the loaded archive originated from.
typedef enum {
    SF64_VER_US     = 0x94F1D5A7,
    SF64_VER_EU     = 0x6EE9ADE7,
    SF64_VER_EU_SPA = 0x3964945f,
    SF64_VER_JP     = 0x3728D3E1
} SF64Version;
ConstantValueRegion
SF64_VER_US0x94F1D5A7North America
SF64_VER_EU0x6EE9ADE7Europe (English/French/German)
SF64_VER_EU_SPA0x3964945fEurope (Spanish/Dutch)
SF64_VER_JP0x3728D3E1Japan

GameEngine C++ Class

GameEngine is a singleton. Access it via GameEngine::Instance after GameEngine::Create() has been called during boot.
class GameEngine {
public:
    static GameEngine* Instance;
    std::shared_ptr<Ship::Context> context;

    GameEngine();
    void StartFrame() const;

    static bool    GenAssetFile(bool exitOnFail = true);
    static void    Create();
    static void    Destroy();
    static void    HandleAudioThread();
    static void    StartAudioFrame();
    static void    EndAudioFrame();
    static void    AudioInit();
    static void    AudioExit();
    static void    RunCommands(Gfx* Commands,
                       const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements);
    static void    ProcessGfxCommands(Gfx* commands);
    static uint32_t GetInterpolationFPS();
    static uint32_t GetInterpolationFrameCount();
    static int     ShowYesNoBox(const char* title, const char* box);
    static void    ShowMessage(const char* title, const char* message,
                       SDL_MessageBoxFlags type = SDL_MESSAGEBOX_ERROR);
    static bool    HasVersion(SF64Version ver);
};

Lifecycle Methods

GameEngine::Create()

static void Create();
Allocates and initializes the singleton (GameEngine::Instance). Registers all resource importers, sets up the libultraship context, and opens the sf64.o2r / starship.o2r archives. Call this exactly once at startup before any other engine function.

GameEngine::Destroy()

static void Destroy();
Shuts down the engine, flushes the audio thread, and frees all memory in the internal pool. Called automatically at clean exit; do not call from mod code during normal gameplay.

StartFrame()

void StartFrame() const;
Begins a new render frame. Reads the current CVar state (alt-assets toggle, gamma mode) and signals the graphics backend to start accepting display list commands.

GenAssetFile(bool exitOnFail)

static bool GenAssetFile(bool exitOnFail = true);
Runs the asset extractor to regenerate sf64.o2r from a ROM if it is missing or stale. When exitOnFail is true (default) the process terminates if extraction fails. Returns true on success.

Graphics Methods

RunCommands()

static void RunCommands(Gfx* Commands,
    const std::vector<std::unordered_map<Mtx*, MtxF>>& mtx_replacements);
Submits a completed N64 display list to the Fast3D interpreter together with interpolated matrix replacements produced by FrameInterpolation_Interpolate(). This is the main rendering entry point called once per rendered frame.
Commands
Gfx*
required
Pointer to the root display list command buffer.
mtx_replacements
std::vector<std::unordered_map<Mtx*, MtxF>>
required
Per-frame matrix replacement maps returned by FrameInterpolation_Interpolate(). Pass an empty vector to skip interpolation.

ProcessGfxCommands()

static void ProcessGfxCommands(Gfx* commands);
Low-level display-list submission that bypasses the interpolation layer. Prefer RunCommands() for normal gameplay rendering; use this only for HUD or debug overlays that must not be interpolated.

GetInterpolationFPS()

static uint32_t GetInterpolationFPS();
Returns the effective interpolation target in frames-per-second. Reads gInterpolationFPS (default 60), but respects gMatchRefreshRate and gVsyncEnabled overrides. Use this value to drive per-frame timing logic in mods that need to be framerate-aware.

GetInterpolationFrameCount()

static uint32_t GetInterpolationFrameCount();
Returns how many rendered frames are produced per N64 game logic tick. Computed as ⌈GetInterpolationFPS() / (60 / gVIsPerFrame)⌉. Useful for distributing per-tick work across sub-frames.

Audio Methods

AudioInit() / AudioExit()

static void AudioInit();
static void AudioExit();
Initialize and tear down the audio backend. Called internally by Create() / Destroy(). Do not call from mod code unless you are replacing the entire audio subsystem.

HandleAudioThread()

static void HandleAudioThread();
Processes queued audio commands on the dedicated audio thread. Called once per game tick by the engine main loop.

StartAudioFrame() / EndAudioFrame()

static void StartAudioFrame();
static void EndAudioFrame();
Bracket the per-frame audio command submission. StartAudioFrame acquires the audio mutex and advances internal timing; EndAudioFrame releases it and triggers sample generation.

Utility Methods

HasVersion()

static bool HasVersion(SF64Version ver);
Returns true when the loaded archive was built from the specified ROM version. Use this to gate version-specific asset paths or behavior differences.
if (GameEngine::HasVersion(SF64_VER_US)) {
    // US-specific logic
}

ShowYesNoBox()

static int ShowYesNoBox(const char* title, const char* box);
Displays a native OS dialog with Yes / No buttons. Returns IDYES (6) or IDNO (7). Blocks the calling thread.
title
const char*
required
Dialog window title.
box
const char*
required
Message body text.

ShowMessage()

static void ShowMessage(const char* title, const char* message,
    SDL_MessageBoxFlags type = SDL_MESSAGEBOX_ERROR);
Displays a native OS message box. type controls the icon: SDL_MESSAGEBOX_ERROR, SDL_MESSAGEBOX_WARNING, or SDL_MESSAGEBOX_INFORMATION.

C API (extern "C")

All functions below are declared with C linkage and are callable from both C and C++ translation units.

Memory

GameEngine_Malloc()

void* GameEngine_Malloc(size_t size);
Allocates size bytes from the engine memory pool. The engine tracks every allocation and frees the entire pool on Destroy(). Prefer this over raw malloc for temporary mod allocations so memory is always reclaimed on shutdown.

Version Check

GameEngine_HasVersion()

bool GameEngine_HasVersion(SF64Version ver);
C-linkage mirror of GameEngine::HasVersion(). Returns true when the loaded archive matches ver.

Graphics

GameEngine_ProcessGfxCommands()

void GameEngine_ProcessGfxCommands(Gfx* commands);
Submits a raw display list without interpolation. C-linkage mirror of the static C++ method.

GameEngine_GetAspectRatio()

float GameEngine_GetAspectRatio();
Returns the current render viewport aspect ratio as a float (e.g. 1.7778 for 16:9). Use when manually computing projection matrices in mod code.

GameEngine_GetInterpolationFrameCount()

uint32_t GameEngine_GetInterpolationFrameCount();
C-linkage mirror of GameEngine::GetInterpolationFrameCount().

Texture Info

GameEngine_GetTextureInfo()

void GameEngine_GetTextureInfo(const char* path,
    int32_t* width, int32_t* height,
    float*   scale,
    bool*    custom);
Fills out metadata for a texture stored in the archive. custom is set to true when the asset was loaded from a player-installed mod rather than the base sf64.o2r.
path
const char*
required
Archive-relative asset path, e.g. "gfx/sprites/arwing.tex".
width
int32_t*
required
Receives the texture width in pixels.
height
int32_t*
required
Receives the texture height in pixels.
scale
float*
required
Receives the stored scale factor (1.0 for unscaled assets).
custom
bool*
required
Receives true if the texture originates from a mod pack.

Archive Check

GameEngine_OTRSigCheck()

uint8_t GameEngine_OTRSigCheck(const char* imgData);
Returns a non-zero value when imgData is a path that exists in the loaded .o2r archive. Used internally by LOAD_ASSET to decide whether to redirect an asset pointer into the archive or pass it through as-is (e.g. a raw ROM pointer).

Viewport / Resolution

OTRGetCurrentWidth() / OTRGetCurrentHeight()

uint32_t OTRGetCurrentWidth(void);
uint32_t OTRGetCurrentHeight(void);
Return the current window dimensions in pixels. These update on resize events; do not cache them across frames.

OTRGetGameRenderWidth() / OTRGetGameRenderHeight()

uint32_t OTRGetGameRenderWidth(void);
uint32_t OTRGetGameRenderHeight(void);
Return the internal game render resolution, which may differ from the window size when integer scaling or a custom internal resolution is active.

HUD Layout

The HUD layout helpers translate N64 fixed-screen coordinates (320 × 240) into the actual viewport, accounting for widescreen, custom HUD aspect ratio overrides, and pillarbox/letterbox regions.
All float-returning variants operate on sub-pixel positions. The int16_t-returning OTRGetRectDimension* variants are drop-in replacements for the Rect macro calls found in the original rendering code.

OTRGetHUDAspectRatio()

float OTRGetHUDAspectRatio();
Returns the effective HUD aspect ratio. When gHUDAspectRatio.Enabled is set and both gHUDAspectRatio.X / gHUDAspectRatio.Y are non-zero, returns the custom ratio; otherwise falls back to the game render aspect ratio.

OTRConvertHUDXToScreenX()

int32_t OTRConvertHUDXToScreenX(int32_t v);
Converts an N64 HUD X coordinate to the physical screen X pixel position.

OTRGetDimensionFromLeftEdge() / OTRGetDimensionFromRightEdge()

float OTRGetDimensionFromLeftEdge(float v);
float OTRGetDimensionFromRightEdge(float v);
Offset v from the left or right edge of the safe HUD area. Use for anchoring HUD elements to screen edges regardless of aspect ratio.

OTRGetRectDimensionFromLeftEdge() / OTRGetRectDimensionFromRightEdge()

int16_t OTRGetRectDimensionFromLeftEdge(float v);
int16_t OTRGetRectDimensionFromRightEdge(float v);
Integer variants of the above, suitable for direct use in Rect/gSPScisTextureRectangle calls.

Forced Aspect Ratio Variants

float   OTRGetDimensionFromLeftEdgeForcedAspect(float v, float aspectRatio);
float   OTRGetDimensionFromRightEdgeForcedAspect(float v, float aspectRatio);
int16_t OTRGetRectDimensionFromLeftEdgeForcedAspect(float v, float aspectRatio);
int16_t OTRGetRectDimensionFromRightEdgeForcedAspect(float v, float aspectRatio);
Same as the standard edge helpers but use aspectRatio instead of the detected render ratio. Pass 4.0f / 3.0f to force original N64 layout.

Override Variants

float   OTRGetDimensionFromLeftEdgeOverride(float v);
float   OTRGetDimensionFromRightEdgeOverride(float v);
int16_t OTRGetRectDimensionFromLeftEdgeOverride(float v);
int16_t OTRGetRectDimensionFromRightEdgeOverride(float v);
Variants that respect the per-element HUD positioning overrides set through the alignment CVars. Use these when an element’s position can be individually reconfigured by the player.

Tile Size Interpolation

gDPSetTileSizeInterp()

void gDPSetTileSizeInterp(Gfx* pkt, int t,
    float uls, float ult,
    float lrs, float lrt);
Emits a gDPSetTileSize command with sub-pixel UV coordinates for use inside interpolated display lists. The standard macro only accepts integer UV values; this variant accepts floats so the interpolation system can produce smooth UV animation.
pkt
Gfx*
required
Pointer to the current display list write position.
t
int
required
Tile descriptor index (0–7).
uls
float
required
Upper-left S coordinate in 10.2 fixed-point units.
ult
float
required
Upper-left T coordinate in 10.2 fixed-point units.
lrs
float
required
Lower-right S coordinate in 10.2 fixed-point units.
lrt
float
required
Lower-right T coordinate in 10.2 fixed-point units.

Macros

Asset Loading

// Load from archive if available; fall back to the original pointer
#define LOAD_ASSET(path) \
    (path == NULL ? NULL \
     : (GameEngine_OTRSigCheck((const char*) path) \
        ? ResourceGetDataByName((const char*) path) \
        : path))

// Always load from archive (no fallback)
#define LOAD_ASSET_RAW(path) ResourceGetDataByName((const char*) path)
Use LOAD_ASSET in ported gameplay code where the pointer might legitimately be a ROM address that hasn’t been archived yet. Use LOAD_ASSET_RAW when you know the asset is always present in the archive, such as a custom mod asset.

Memory Allocation

// Allocate n instances of type from the engine pool
#define memallocn(type, n) (type*) GameEngine_Malloc(sizeof(type) * n)

// Allocate a single instance of type
#define memalloc(type) memallocn(type, 1)
// Allocate a single actor struct
MyActor* actor = memalloc(MyActor);

// Allocate an array of 16 vertices
Vtx* verts = memallocn(Vtx, 16);
Memory allocated via memalloc / memallocn is tracked by the engine pool and released en-masse when GameEngine::Destroy() is called. Do not call free() on these pointers — doing so will cause a double-free on shutdown.

Build docs developers (and LLMs) love