Skip to content

SDL2 exporter ​

How it works ​

Packrat writes a self-contained C header and one image file per atlas page. The header defines the shared Packrat_* types, loading and lookup helpers, and a renderer helper. packrat_load creates one SDL_Texture per page; packrat_draw uses the packed rectangle, trim offset, and original frame size to place the frame correctly.

Several generated SDL2 headers can be included together. The common API is guarded once, while each header keeps its own definition object. SDL2 and SDL3 headers must not be mixed in one translation unit.

API ​

The generated header defines these SDL2-backed types:

c
typedef struct Packrat_frame {
    const char *name;
    int page;
    SDL_Rect source;
    SDL_Point original_size;
    SDL_Point offset;
    bool rotated;
    int index;
} Packrat_frame;

typedef struct Packrat_animation {
    const char *name;
    const Packrat_frame *const *frames;
    size_t frame_count;
} Packrat_animation;

typedef struct Packrat_atlas_definition {
    const char *const *page_paths;
    size_t page_count;
    const Packrat_frame *frames;
    size_t frame_count;
    const Packrat_animation *animations;
    size_t animation_count;
} Packrat_atlas_definition;

typedef struct Packrat_atlas {
    const Packrat_atlas_definition *definition;
    SDL_Texture **pages;
    size_t page_count;
} Packrat_atlas;

The generated definition object is named packrat_<stem>_definition. The header provides these exact helpers:

c
static inline bool packrat_load(
    Packrat_atlas *atlas,
    const Packrat_atlas_definition *definition,
    SDL_Renderer *renderer,
    const char *asset_directory);
static inline void packrat_unload(Packrat_atlas *atlas);
static inline const Packrat_frame *packrat_frame_at(
    const Packrat_atlas *atlas, size_t index);
static inline const Packrat_frame *packrat_find(
    const Packrat_atlas *atlas, const char *name, int index);
static inline const Packrat_animation *packrat_find_animation(
    const Packrat_atlas *atlas, const char *name);
static inline void packrat_draw(
    SDL_Renderer *renderer,
    const Packrat_atlas *atlas,
    const Packrat_frame *frame,
    float x, float y, float rotation,
    float scale_x, float scale_y,
    SDL_RendererFlip flip);

packrat_find treats a negative index as the first matching frame. packrat_load returns false on invalid input or an SDL_image loading failure; the other lookup helpers return NULL when they cannot find a result. packrat_draw applies trim metadata, rotation, scaling, and the provided SDL_RendererFlip value.

Integrate ​

Initialize SDL2 and SDL_image, create a renderer, and include the generated header. The draw call can then use a frame from an animation:

c
#include <SDL.h>
#include <SDL_image.h>
#include "atlas.h"

void draw_example(SDL_Renderer *renderer) {
    Packrat_atlas atlas = {0};
    if (!packrat_load(&atlas, &packrat_atlas_definition, renderer, "assets")) return;

    const Packrat_animation *run = packrat_find_animation(&atlas, "run_side");
    const Packrat_frame *frame = run && run->frame_count > 0
        ? run->frames[0]
        : NULL;

    SDL_SetRenderDrawColor(renderer, 18, 24, 32, 255);
    SDL_RenderClear(renderer);
    packrat_draw(renderer, &atlas, frame, 400.0f, 300.0f, 0.0f,
        2.0f, 2.0f, SDL_FLIP_NONE);
    SDL_RenderPresent(renderer);

    packrat_unload(&atlas);
}

The definition symbol uses the export base name, such as packrat_characters_definition. Replace .png in generated page paths with the image extension selected for the export.

Packrat documentation