From 5294ea7acb86de460e2426a6dac1d281979d0c3b Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Thu, 4 Sep 2025 19:16:32 -0700 Subject: Rename isogfx -> gfx2d --- demos/checkerboard/checkerboard.c | 62 +++---- demos/isomap/isomap.c | 50 ++--- include/isogfx/backend.h | 29 +-- include/isogfx/gfx2d.h | 54 +++--- src/backend.c | 28 +-- src/gfx2d.c | 381 +++++++++++++++++++------------------- 6 files changed, 303 insertions(+), 301 deletions(-) diff --git a/demos/checkerboard/checkerboard.c b/demos/checkerboard/checkerboard.c index 4f43526..467da61 100644 --- a/demos/checkerboard/checkerboard.c +++ b/demos/checkerboard/checkerboard.c @@ -47,21 +47,21 @@ typedef enum Colour { } Colour; typedef struct GfxAppState { - IsoBackend* backend; - IsoGfx* iso; - Tile red; - int xpick; - int ypick; + Gfx2dBackend* backend; + Gfx2d* gfx; + Tile red; + int xpick; + int ypick; } GfxAppState; -static void make_checkerboard(IsoGfx* iso, Tile black, Tile white) { +static void make_checkerboard(Gfx2d* iso, Tile black, Tile white) { assert(iso); - for (int y = 0; y < isogfx_world_height(iso); ++y) { - for (int x = 0; x < isogfx_world_width(iso); ++x) { + for (int y = 0; y < gfx2d_world_height(iso); ++y) { + for (int x = 0; x < gfx2d_world_width(iso); ++x) { const int odd_col = x & 1; const int odd_row = y & 1; const Tile value = (odd_row ^ odd_col) == 0 ? black : white; - isogfx_set_tile(iso, x, y, value); + gfx2d_set_tile(iso, x, y, value); } } } @@ -72,28 +72,28 @@ static bool init(GfxApp* app, GfxAppState* state, int argc, const char** argv) { (void)argc; (void)argv; - if (!((state->iso = - isogfx_new(&(IsoGfxDesc){.memory = MEMORY, - .memory_size = MEMORY_SIZE, - .screen_width = SCREEN_WIDTH, - .screen_height = SCREEN_HEIGHT})))) { + if (!((state->gfx = + gfx2d_new(&(Gfx2dDesc){.memory = MEMORY, + .memory_size = MEMORY_SIZE, + .screen_width = SCREEN_WIDTH, + .screen_height = SCREEN_HEIGHT})))) { return false; } - IsoGfx* iso = state->iso; + Gfx2d* iso = state->gfx; - isogfx_make_map( + gfx2d_make_map( iso, &(MapDesc){.tile_width = TILE_WIDTH, .tile_height = TILE_HEIGHT, .world_width = WORLD_WIDTH, .world_height = WORLD_HEIGHT, .num_tiles = NUM_TILES}); - const Tile black = isogfx_make_tile(iso, &tile_set[Black]); - const Tile white = isogfx_make_tile(iso, &tile_set[White]); - state->red = isogfx_make_tile(iso, &tile_set[Red]); + const Tile black = gfx2d_make_tile(iso, &tile_set[Black]); + const Tile white = gfx2d_make_tile(iso, &tile_set[White]); + state->red = gfx2d_make_tile(iso, &tile_set[Red]); make_checkerboard(iso, black, white); - if (!((state->backend = iso_backend_init(iso)))) { + if (!((state->backend = gfx2d_backend_init(iso)))) { return false; } @@ -104,8 +104,8 @@ static void shutdown(GfxApp* app, GfxAppState* state) { assert(app); assert(state); - iso_backend_shutdown(&state->backend); - isogfx_del(&state->iso); + gfx2d_backend_shutdown(&state->backend); + gfx2d_del(&state->gfx); } static void update(GfxApp* app, GfxAppState* state, double t, double dt) { @@ -113,19 +113,19 @@ static void update(GfxApp* app, GfxAppState* state, double t, double dt) { assert(state); (void)dt; - IsoGfx* iso = state->iso; + Gfx2d* iso = state->gfx; - isogfx_update(iso, t); + gfx2d_update(iso, t); // Get mouse position in window coordinates. double mouse_x, mouse_y; gfx_app_get_mouse_position(app, &mouse_x, &mouse_y); // Map from window coordinates to virtual screen coordinates. - iso_backend_get_mouse_position( + gfx2d_backend_get_mouse_position( state->backend, mouse_x, mouse_y, &mouse_x, &mouse_y); - isogfx_pick_tile(iso, mouse_x, mouse_y, &state->xpick, &state->ypick); + gfx2d_pick_tile(iso, mouse_x, mouse_y, &state->xpick, &state->ypick); printf("Picked tile: (%d, %d)\n", state->xpick, state->ypick); } @@ -134,22 +134,22 @@ static void render(const GfxApp* app, GfxAppState* state) { assert(app); assert(state); - IsoGfx* iso = state->iso; + Gfx2d* iso = state->gfx; - isogfx_render(iso); + gfx2d_render(iso); if ((state->xpick != -1) && (state->ypick != -1)) { - isogfx_draw_tile(iso, state->xpick, state->ypick, state->red); + gfx2d_draw_tile(iso, state->xpick, state->ypick, state->red); } - iso_backend_render(state->backend, iso); + gfx2d_backend_render(state->backend, iso); } static void resize(GfxApp* app, GfxAppState* state, int width, int height) { assert(app); assert(state); - iso_backend_resize_window(state->backend, state->iso, width, height); + gfx2d_backend_resize_window(state->backend, state->gfx, width, height); } int main(int argc, const char** argv) { diff --git a/demos/isomap/isomap.c b/demos/isomap/isomap.c index bca27f6..471ef57 100644 --- a/demos/isomap/isomap.c +++ b/demos/isomap/isomap.c @@ -22,13 +22,13 @@ static const R CAMERA_SPEED = 800; uint8_t MEMORY[MEMORY_SIZE]; typedef struct GfxAppState { - IsoBackend* backend; - IsoGfx* iso; - int xpick; - int ypick; - vec2 camera; - SpriteSheet stag_sheet; - Sprite stag; + Gfx2dBackend* backend; + Gfx2d* gfx; + int xpick; + int ypick; + vec2 camera; + SpriteSheet stag_sheet; + Sprite stag; } GfxAppState; static bool init(GfxApp* app, GfxAppState* state, int argc, const char** argv) { @@ -37,31 +37,31 @@ static bool init(GfxApp* app, GfxAppState* state, int argc, const char** argv) { (void)argc; (void)argv; - if (!((state->iso = - isogfx_new(&(IsoGfxDesc){.memory = MEMORY, - .memory_size = MEMORY_SIZE, - .screen_width = SCREEN_WIDTH, - .screen_height = SCREEN_HEIGHT})))) { + if (!((state->gfx = + gfx2d_new(&(Gfx2dDesc){.memory = MEMORY, + .memory_size = MEMORY_SIZE, + .screen_width = SCREEN_WIDTH, + .screen_height = SCREEN_HEIGHT})))) { return false; } - IsoGfx* iso = state->iso; + Gfx2d* iso = state->gfx; - if (!isogfx_load_map( + if (!gfx2d_load_map( iso, "/home/jeanne/Nextcloud/assets/tilemaps/scrabling1.tm")) { return false; } - if (!((state->stag_sheet = isogfx_load_sprite_sheet( + if (!((state->stag_sheet = gfx2d_load_sprite_sheet( iso, "/home/jeanne/Nextcloud/assets/tilesets/scrabling/critters/stag/" "stag.ss")))) { return false; } - state->stag = isogfx_make_sprite(iso, state->stag_sheet); - isogfx_set_sprite_position(iso, state->stag, 0, 0); + state->stag = gfx2d_make_sprite(iso, state->stag_sheet); + gfx2d_set_sprite_position(iso, state->stag, 0, 0); - if (!((state->backend = iso_backend_init(iso)))) { + if (!((state->backend = gfx2d_backend_init(iso)))) { return false; } @@ -101,25 +101,25 @@ static void update(GfxApp* app, GfxAppState* state, double t, double dt) { state->camera = vec2_add(state->camera, get_camera_movement(app, (R)dt)); - IsoGfx* iso = state->iso; - isogfx_set_camera(iso, (int)state->camera.x, (int)state->camera.y); - isogfx_update(iso, t); + Gfx2d* iso = state->gfx; + gfx2d_set_camera(iso, (int)state->camera.x, (int)state->camera.y); + gfx2d_update(iso, t); } static void render(const GfxApp* app, GfxAppState* state) { assert(app); assert(state); - IsoGfx* iso = state->iso; - isogfx_render(iso); - iso_backend_render(state->backend, iso); + Gfx2d* iso = state->gfx; + gfx2d_render(iso); + gfx2d_backend_render(state->backend, iso); } static void resize(GfxApp* app, GfxAppState* state, int width, int height) { assert(app); assert(state); - iso_backend_resize_window(state->backend, state->iso, width, height); + gfx2d_backend_resize_window(state->backend, state->gfx, width, height); } int main(int argc, const char** argv) { diff --git a/include/isogfx/backend.h b/include/isogfx/backend.h index 76ee13d..86afed5 100644 --- a/include/isogfx/backend.h +++ b/include/isogfx/backend.h @@ -2,28 +2,29 @@ #include -typedef struct Gfx Gfx; -typedef struct IsoGfx IsoGfx; +typedef struct Gfx Gfx; +typedef struct Gfx2d Gfx2d; -typedef struct IsoBackend IsoBackend; +typedef struct Gfx2dBackend Gfx2dBackend; /// Initialize the backend. -IsoBackend* iso_backend_init(const IsoGfx*); +Gfx2dBackend* gfx2d_backend_init(const Gfx2d*); /// Shut down the backend. -void iso_backend_shutdown(IsoBackend**); +void gfx2d_backend_shutdown(Gfx2dBackend**); /// Notify the backend of a window resize event. -/// This allows the backend to determine how to position and scale the iso +/// This allows the backend to determine how to position and scale the gfx /// screen buffer on the graphics window. -void iso_backend_resize_window( - IsoBackend*, const IsoGfx*, int width, int height); +void gfx2d_backend_resize_window( + Gfx2dBackend*, const Gfx2d*, int width, int height); -/// Render the iso screen to the graphics window. -void iso_backend_render(const IsoBackend*, const IsoGfx*); +/// Render the gfx screen to the graphics window. +void gfx2d_backend_render(const Gfx2dBackend*, const Gfx2d*); -/// Map window coordinates to iso space coordinates. +/// Map window coordinates to gfx space coordinates. /// This takes into account any possible resizing done by the backend in -/// response to calls to iso_backend_resize_window(). -bool iso_backend_get_mouse_position( - const IsoBackend*, double window_x, double window_y, double* x, double* y); +/// response to calls to gfx2d_backend_resize_window(). +bool gfx2d_backend_get_mouse_position( + const Gfx2dBackend*, double window_x, double window_y, double* x, + double* y); diff --git a/include/isogfx/gfx2d.h b/include/isogfx/gfx2d.h index 323b389..59566f3 100644 --- a/include/isogfx/gfx2d.h +++ b/include/isogfx/gfx2d.h @@ -8,7 +8,7 @@ #include #include -typedef struct IsoGfx IsoGfx; +typedef struct Gfx2d Gfx2d; /// Sprite sheet handle. typedef uintptr_t SpriteSheet; @@ -50,43 +50,43 @@ typedef struct IsoGfxDesc { size_t memory_size; // Size of memory block in bytes. int screen_width; // Screen width in pixels. int screen_height; // Screen height in pixels. -} IsoGfxDesc; +} Gfx2dDesc; /// Create a new isometric graphics engine. -IsoGfx* isogfx_new(const IsoGfxDesc*); +Gfx2d* gfx2d_new(const Gfx2dDesc*); /// Destroy the isometric graphics engine. -void isogfx_del(IsoGfx**); +void gfx2d_del(Gfx2d**); /// Clear all loaded worlds and sprites. -void isogfx_clear(IsoGfx*); +void gfx2d_clear(Gfx2d*); /// Create an empty map. -void isogfx_make_map(IsoGfx*, const MapDesc*); +void gfx2d_make_map(Gfx2d*, const MapDesc*); /// Load a tile map (.TM) file. -bool isogfx_load_map(IsoGfx*, const char* filepath); +bool gfx2d_load_map(Gfx2d*, const char* filepath); /// Return the world's width. -int isogfx_world_width(const IsoGfx*); +int gfx2d_world_width(const Gfx2d*); /// Return the world's height. -int isogfx_world_height(const IsoGfx*); +int gfx2d_world_height(const Gfx2d*); /// Create a new tile. -Tile isogfx_make_tile(IsoGfx*, const TileDesc*); +Tile gfx2d_make_tile(Gfx2d*, const TileDesc*); /// Set the tile at position (x,y). -void isogfx_set_tile(IsoGfx*, int x, int y, Tile); +void gfx2d_set_tile(Gfx2d*, int x, int y, Tile); /// Set the tiles in positions in the range (x0,y0) - (x1,y1). -void isogfx_set_tiles(IsoGfx*, int x0, int y0, int x1, int y1, Tile); +void gfx2d_set_tiles(Gfx2d*, int x0, int y0, int x1, int y1, Tile); /// Load a sprite sheet (.SS) file. -SpriteSheet isogfx_load_sprite_sheet(IsoGfx*, const char* filepath); +SpriteSheet gfx2d_load_sprite_sheet(Gfx2d*, const char* filepath); /// Create an animated sprite. -Sprite isogfx_make_sprite(IsoGfx*, SpriteSheet); +Sprite gfx2d_make_sprite(Gfx2d*, SpriteSheet); // TODO: Add a function to delete a sprite. Making the caller manage and re-use // sprites is a shitty API. @@ -94,41 +94,41 @@ Sprite isogfx_make_sprite(IsoGfx*, SpriteSheet); // list of sprites so that we can re-use the ones that have been "freed". /// Set the sprite's position. -void isogfx_set_sprite_position(IsoGfx*, Sprite, int x, int y); +void gfx2d_set_sprite_position(Gfx2d*, Sprite, int x, int y); /// Set the sprite's current animation. -void isogfx_set_sprite_animation(IsoGfx*, Sprite, int animation); +void gfx2d_set_sprite_animation(Gfx2d*, Sprite, int animation); /// Update the renderer. /// /// Currently, this updates the sprite animations. -void isogfx_update(IsoGfx*, double t); +void gfx2d_update(Gfx2d*, double t); // TODO: Do we really need to store the camera in the library? It's not used // for anything other than to render, so we could remove library state and // take a camera argument in render() instead. /// Set the camera. -void isogfx_set_camera(IsoGfx*, int x, int y); +void gfx2d_set_camera(Gfx2d*, int x, int y); /// Render the world. -void isogfx_render(IsoGfx*); +void gfx2d_render(Gfx2d*); /// Draw/overlay a tile at position (x,y). /// /// This function just renders a tile at position (x,y) and should be called -/// after isogfx_render() to obtain the correct result. To set the tile at -/// position (x,y) instead, use isogfx_set_tile(). -void isogfx_draw_tile(IsoGfx*, int x, int y, Tile); +/// after gfx2d_render() to obtain the correct result. To set the tile at +/// position (x,y) instead, use gfx2d_set_tile(). +void gfx2d_draw_tile(Gfx2d*, int x, int y, Tile); /// Get the virtual screen's dimensions. -void isogfx_get_screen_size(const IsoGfx*, int* width, int* height); +void gfx2d_get_screen_size(const Gfx2d*, int* width, int* height); /// Return a pointer to the virtual screen's colour buffer. /// -/// Call after each call to isogfx_render() to retrieve the render output. -const Pixel* isogfx_get_screen_buffer(const IsoGfx*); +/// Call after each call to gfx2d_render() to retrieve the render output. +const Pixel* gfx2d_get_screen_buffer(const Gfx2d*); /// Translate Cartesian to isometric coordinates. -void isogfx_pick_tile( - const IsoGfx*, double xcart, double ycart, int* xiso, int* yiso); +void gfx2d_pick_tile( + const Gfx2d*, double xcart, double ycart, int* xiso, int* yiso); diff --git a/src/backend.c b/src/backend.c index 80c5974..4bb3592 100644 --- a/src/backend.c +++ b/src/backend.c @@ -13,7 +13,7 @@ #include #include -typedef struct IsoBackend { +typedef struct Gfx2dBackend { Gfx* gfx; Mesh* quad_mesh; /// The screen or "iso screen" refers to the colour buffer of the iso graphics @@ -29,12 +29,12 @@ typedef struct IsoBackend { int viewport_x, viewport_y, viewport_width, viewport_height; double stretch; // Stretch factor from iso screen dimensions to viewport // dimensions. -} IsoBackend; +} Gfx2dBackend; -IsoBackend* iso_backend_init(const IsoGfx* iso) { +Gfx2dBackend* gfx2d_backend_init(const Gfx2d* iso) { assert(iso); - IsoBackend* backend = calloc(1, sizeof(IsoBackend)); + Gfx2dBackend* backend = calloc(1, sizeof(Gfx2dBackend)); if (!backend) { return nullptr; } @@ -45,7 +45,7 @@ IsoBackend* iso_backend_init(const IsoGfx* iso) { GfxCore* gfxcore = gfx_get_core(backend->gfx); int screen_width, screen_height; - isogfx_get_screen_size(iso, &screen_width, &screen_height); + gfx2d_get_screen_size(iso, &screen_width, &screen_height); if (!((backend->screen_texture = gfx_make_texture( gfxcore, &(TextureDesc){.width = screen_width, @@ -95,10 +95,10 @@ cleanup: return nullptr; } -void iso_backend_shutdown(IsoBackend** ppApp) { +void gfx2d_backend_shutdown(Gfx2dBackend** ppApp) { assert(ppApp); - IsoBackend* app = *ppApp; + Gfx2dBackend* app = *ppApp; if (!app) { return; } @@ -106,8 +106,8 @@ void iso_backend_shutdown(IsoBackend** ppApp) { gfx_destroy(&app->gfx); } -void iso_backend_resize_window( - IsoBackend* app, const IsoGfx* iso, int width, int height) { +void gfx2d_backend_resize_window( + Gfx2dBackend* app, const Gfx2d* iso, int width, int height) { assert(app); assert(iso); @@ -116,7 +116,7 @@ void iso_backend_resize_window( // Virtual screen dimensions. int screen_width, screen_height; - isogfx_get_screen_size(iso, &screen_width, &screen_height); + gfx2d_get_screen_size(iso, &screen_width, &screen_height); // Stretch the virtual screen onto the viewport while respecting the screen's // aspect ratio to prevent distortion. @@ -135,11 +135,11 @@ void iso_backend_resize_window( } } -void iso_backend_render(const IsoBackend* app, const IsoGfx* iso) { +void gfx2d_backend_render(const Gfx2dBackend* app, const Gfx2d* iso) { assert(app); assert(iso); - const Pixel* screen = isogfx_get_screen_buffer(iso); + const Pixel* screen = gfx2d_get_screen_buffer(iso); assert(screen); gfx_update_texture(app->screen_texture, &(TextureDataDesc){.pixels = screen}); @@ -162,8 +162,8 @@ void iso_backend_render(const IsoBackend* app, const IsoGfx* iso) { gfx_end_frame(gfxcore); } -bool iso_backend_get_mouse_position( - const IsoBackend* app, double window_x, double window_y, double* x, +bool gfx2d_backend_get_mouse_position( + const Gfx2dBackend* app, double window_x, double window_y, double* x, double* y) { assert(app); diff --git a/src/gfx2d.c b/src/gfx2d.c index 698e32c..266a5f7 100644 --- a/src/gfx2d.c +++ b/src/gfx2d.c @@ -32,11 +32,11 @@ typedef struct vec2 { // Renderer state. // ----------------------------------------------------------------------------- -typedef struct CoordSystem { +typedef struct IsoCoordSystem { ivec2 o; // Origin. ivec2 x; ivec2 y; -} CoordSystem; +} IsoCoordSystem; typedef struct Screen { int width; @@ -52,9 +52,9 @@ typedef struct SpriteInstance { int frame; // Current frame of animation. } SpriteInstance; -typedef struct IsoGfx { +typedef struct Gfx2d { Screen screen; - CoordSystem iso_space; + IsoCoordSystem iso_space; ivec2 camera; double last_animation_time; Tile next_tile; // For procedurally-generated tiles. @@ -63,7 +63,7 @@ typedef struct IsoGfx { SpriteInstance* head_sprite; // Head of sprites list. memstack stack; size_t watermark; -} IsoGfx; +} Gfx2d; // ----------------------------------------------------------------------------- // Math and world / tile / screen access. @@ -102,7 +102,7 @@ static ivec2 map2screen( /// Create the basis for the isometric coordinate system with origin and vectors /// expressed in the Cartesian system. -static CoordSystem make_iso_coord_system( +static IsoCoordSystem make_iso_coord_system( const Tm_Map* const map, const Screen* const screen) { assert(map); assert(screen); @@ -111,7 +111,7 @@ static CoordSystem make_iso_coord_system( .x = map->base_tile_width / 2, .y = map->base_tile_height / 2}; const ivec2 y = { .x = -map->base_tile_width / 2, .y = map->base_tile_height / 2}; - return (CoordSystem){o, x, y}; + return (IsoCoordSystem){o, x, y}; } /// Map isometric coordinates to Cartesian coordinates. @@ -121,7 +121,7 @@ static CoordSystem make_iso_coord_system( /// /// Takes the camera displacement into account. static ivec2 iso2cart( - const CoordSystem iso_space, ivec2 camera, int iso_x, int iso_y) { + const IsoCoordSystem iso_space, ivec2 camera, int iso_x, int iso_y) { const ivec2 vx_offset = ivec2_scale(iso_space.x, iso_x); const ivec2 vy_offset = ivec2_scale(iso_space.y, iso_y); const ivec2 origin_world_space = @@ -170,63 +170,63 @@ static inline Pixel* screen_xy_mut(Screen* screen, int x, int y) { // Renderer, world and tile management. // ----------------------------------------------------------------------------- -IsoGfx* isogfx_new(const IsoGfxDesc* desc) { +Gfx2d* gfx2d_new(const Gfx2dDesc* desc) { assert(desc->screen_width > 0); assert(desc->screen_height > 0); // Part of our implementation assumes even widths and heights for precision. assert((desc->screen_width & 1) == 0); assert((desc->screen_height & 1) == 0); - IsoGfx tmp = {0}; + Gfx2d tmp = {0}; if (!memstack_make(&tmp.stack, desc->memory_size, desc->memory)) { goto cleanup; } - IsoGfx* iso = - memstack_alloc_aligned(&tmp.stack, sizeof(IsoGfx), alignof(IsoGfx)); - *iso = tmp; + Gfx2d* gfx = + memstack_alloc_aligned(&tmp.stack, sizeof(Gfx2d), alignof(Gfx2d)); + *gfx = tmp; const size_t screen_size_bytes = desc->screen_width * desc->screen_height * sizeof(Pixel); Pixel* screen = - memstack_alloc_aligned(&iso->stack, screen_size_bytes, alignof(Pixel)); + memstack_alloc_aligned(&gfx->stack, screen_size_bytes, alignof(Pixel)); - iso->screen = (Screen){.width = desc->screen_width, + gfx->screen = (Screen){.width = desc->screen_width, .height = desc->screen_height, .pixels = screen}; - iso->last_animation_time = 0.0; - iso->watermark = memstack_watermark(&iso->stack); + gfx->last_animation_time = 0.0; + gfx->watermark = memstack_watermark(&gfx->stack); - return iso; + return gfx; cleanup: - isogfx_del(&iso); + gfx2d_del(&gfx); return nullptr; } -void isogfx_clear(IsoGfx* iso) { - assert(iso); - iso->last_animation_time = 0.0; - iso->next_tile = 0; - iso->map = nullptr; - iso->tileset = nullptr; - iso->head_sprite = nullptr; - // The base of the stack contains the IsoGfx and the screen buffer. Make sure +void gfx2d_clear(Gfx2d* gfx) { + assert(gfx); + gfx->last_animation_time = 0.0; + gfx->next_tile = 0; + gfx->map = nullptr; + gfx->tileset = nullptr; + gfx->head_sprite = nullptr; + // The base of the stack contains the Gfx2d and the screen buffer. Make sure // we don't clear them. - memstack_set_watermark(&iso->stack, iso->watermark); + memstack_set_watermark(&gfx->stack, gfx->watermark); } -void isogfx_del(IsoGfx** ppIso) { - assert(ppIso); - IsoGfx* iso = *ppIso; - if (iso) { - memstack_del(&iso->stack); - *ppIso = nullptr; +void gfx2d_del(Gfx2d** ppGfx) { + assert(ppGfx); + Gfx2d* gfx = *ppGfx; + if (gfx) { + memstack_del(&gfx->stack); + *ppGfx = nullptr; } } -void isogfx_make_map(IsoGfx* iso, const MapDesc* desc) { - assert(iso); +void gfx2d_make_map(Gfx2d* gfx, const MapDesc* desc) { + assert(gfx); assert(desc); assert(desc->tile_width > 0); assert(desc->tile_height > 0); @@ -241,7 +241,7 @@ void isogfx_make_map(IsoGfx* iso, const MapDesc* desc) { assert(desc->num_tiles > 0); // Handle recreation by destroying the previous world and sprites. - isogfx_clear(iso); + gfx2d_clear(gfx); const int world_size = desc->world_width * desc->world_height; const size_t map_size_bytes = sizeof(Tm_Map) + (world_size * sizeof(Tile)); @@ -256,8 +256,8 @@ void isogfx_make_map(IsoGfx* iso, const MapDesc* desc) { (desc->num_tiles * sizeof(Ts_Tile)) + tile_data_size_bytes; - iso->map = memstack_alloc_aligned(&iso->stack, map_size_bytes, 4); - *iso->map = (Tm_Map){ + gfx->map = memstack_alloc_aligned(&gfx->stack, map_size_bytes, 4); + *gfx->map = (Tm_Map){ .world_width = desc->world_width, .world_height = desc->world_height, .base_tile_width = desc->tile_width, @@ -265,34 +265,34 @@ void isogfx_make_map(IsoGfx* iso, const MapDesc* desc) { .num_layers = 1, }; - iso->tileset = memstack_alloc_aligned(&iso->stack, tileset_size_bytes, 4); - *iso->tileset = (Ts_TileSet){ + gfx->tileset = memstack_alloc_aligned(&gfx->stack, tileset_size_bytes, 4); + *gfx->tileset = (Ts_TileSet){ .num_tiles = desc->num_tiles, }; - iso->iso_space = make_iso_coord_system(iso->map, &iso->screen); + gfx->iso_space = make_iso_coord_system(gfx->map, &gfx->screen); } -bool isogfx_load_map(IsoGfx* iso, const char* filepath) { - assert(iso); +bool gfx2d_load_map(Gfx2d* gfx, const char* filepath) { + assert(gfx); assert(filepath); bool success = false; // Handle recreation by destroying the previous world and sprites. - isogfx_clear(iso); + gfx2d_clear(gfx); // Load the map. printf("Load tile map: %s\n", filepath); WITH_FILE(filepath, { const size_t map_size = get_file_size_f(file); - iso->map = memstack_alloc_aligned(&iso->stack, map_size, 4); - success = read_file_f(file, iso->map); + gfx->map = memstack_alloc_aligned(&gfx->stack, map_size, 4); + success = read_file_f(file, gfx->map); }); if (!success) { goto cleanup; } - Tm_Map* const map = iso->map; + Tm_Map* const map = gfx->map; printf("Map orientation: %d\n", ((Tm_Flags*)&map->flags)->orientation); @@ -308,39 +308,39 @@ bool isogfx_load_map(IsoGfx* iso, const char* filepath) { printf("Load tile set: %s\n", ts_path_cwd); WITH_FILE(ts_path_cwd, { const size_t file_size = get_file_size_f(file); - iso->tileset = memstack_alloc_aligned(&iso->stack, file_size, 4); - success = read_file_f(file, iso->tileset); + gfx->tileset = memstack_alloc_aligned(&gfx->stack, file_size, 4); + success = read_file_f(file, gfx->tileset); }); if (!success) { // TODO: Log errors using the log library. goto cleanup; } - const Ts_TileSet* const tileset = iso->tileset; + const Ts_TileSet* const tileset = gfx->tileset; printf("Loaded tile set (%u tiles): %s\n", tileset->num_tiles, ts_path_cwd); // TODO: These assertions on input data should be library runtime errors. assert(ts_validate_tileset(tileset)); assert(tm_validate_map(map, tileset)); - iso->iso_space = make_iso_coord_system(iso->map, &iso->screen); + gfx->iso_space = make_iso_coord_system(gfx->map, &gfx->screen); success = true; cleanup: if (!success) { - isogfx_clear(iso); + gfx2d_clear(gfx); } return success; } -int isogfx_world_width(const IsoGfx* iso) { - assert(iso); - return iso->map->world_width; +int gfx2d_world_width(const Gfx2d* gfx) { + assert(gfx); + return gfx->map->world_width; } -int isogfx_world_height(const IsoGfx* iso) { - assert(iso); - return iso->map->world_height; +int gfx2d_world_height(const Gfx2d* gfx) { + assert(gfx); + return gfx->map->world_height; } static void make_tile_from_colour( @@ -368,19 +368,19 @@ static void make_tile_from_colour( } } -Tile isogfx_make_tile(IsoGfx* iso, const TileDesc* desc) { - assert(iso); +Tile gfx2d_make_tile(Gfx2d* gfx, const TileDesc* desc) { + assert(gfx); assert(desc); // Client must create a world first. - assert(iso->map); - assert(iso->tileset); + assert(gfx->map); + assert(gfx->tileset); // Currently, procedural tiles must match the base tile size. - assert(desc->width == iso->map->base_tile_width); - assert(desc->height == iso->map->base_tile_height); + assert(desc->width == gfx->map->base_tile_width); + assert(desc->height == gfx->map->base_tile_height); // Cannot exceed max tiles. - assert(iso->next_tile < iso->tileset->num_tiles); + assert(gfx->next_tile < gfx->tileset->num_tiles); - const Tile tile = iso->next_tile++; + const Tile tile = gfx->next_tile++; const size_t tile_size_bytes = desc->width * desc->height * sizeof(Pixel); @@ -389,16 +389,16 @@ Tile isogfx_make_tile(IsoGfx* iso, const TileDesc* desc) { assert(desc->width > 0); assert(desc->height > 0); - Ts_Tile* const ts_tile = ts_tileset_get_tile_mut(iso->tileset, tile); + Ts_Tile* const ts_tile = ts_tileset_get_tile_mut(gfx->tileset, tile); *ts_tile = (Ts_Tile){ - .width = iso->map->base_tile_width, - .height = iso->map->base_tile_height, + .width = gfx->map->base_tile_width, + .height = gfx->map->base_tile_height, .pixels = tile * tile_size_bytes, }; Pixel* const tile_pixels = - ts_tileset_get_tile_pixels_mut(iso->tileset, tile); + ts_tileset_get_tile_pixels_mut(gfx->tileset, tile); make_tile_from_colour(desc->colour, ts_tile, tile_pixels); break; } @@ -416,31 +416,31 @@ Tile isogfx_make_tile(IsoGfx* iso, const TileDesc* desc) { return tile; } -void isogfx_set_tile(IsoGfx* iso, int x, int y, Tile tile) { - assert(iso); +void gfx2d_set_tile(Gfx2d* gfx, int x, int y, Tile tile) { + assert(gfx); - Tm_Layer* const layer = tm_map_get_layer_mut(iso->map, 0); - Tile* map_tile = tm_layer_get_tile_mut(iso->map, layer, x, y); + Tm_Layer* const layer = tm_map_get_layer_mut(gfx->map, 0); + Tile* map_tile = tm_layer_get_tile_mut(gfx->map, layer, x, y); *map_tile = tile; } -void isogfx_set_tiles(IsoGfx* iso, int x0, int y0, int x1, int y1, Tile tile) { - assert(iso); +void gfx2d_set_tiles(Gfx2d* gfx, int x0, int y0, int x1, int y1, Tile tile) { + assert(gfx); for (int y = y0; y < y1; ++y) { for (int x = x0; x < x1; ++x) { - isogfx_set_tile(iso, x, y, tile); + gfx2d_set_tile(gfx, x, y, tile); } } } -SpriteSheet isogfx_load_sprite_sheet(IsoGfx* iso, const char* filepath) { - assert(iso); +SpriteSheet gfx2d_load_sprite_sheet(Gfx2d* gfx, const char* filepath) { + assert(gfx); assert(filepath); bool success = false; SpriteSheet spriteSheet = 0; - const size_t watermark = memstack_watermark(&iso->stack); + const size_t watermark = memstack_watermark(&gfx->stack); // Load sprite sheet file. printf("Load sprite sheet: %s\n", filepath); @@ -448,7 +448,7 @@ SpriteSheet isogfx_load_sprite_sheet(IsoGfx* iso, const char* filepath) { WITH_FILE(filepath, { const size_t file_size = get_file_size_f(file); ss_sheet = - memstack_alloc_aligned(&iso->stack, file_size, alignof(Ss_SpriteSheet)); + memstack_alloc_aligned(&gfx->stack, file_size, alignof(Ss_SpriteSheet)); success = read_file_f(file, ss_sheet); }); if (!success) { @@ -461,63 +461,63 @@ SpriteSheet isogfx_load_sprite_sheet(IsoGfx* iso, const char* filepath) { cleanup: if (!success) { if (ss_sheet) { - memstack_set_watermark(&iso->stack, watermark); + memstack_set_watermark(&gfx->stack, watermark); } } return spriteSheet; } -Sprite isogfx_make_sprite(IsoGfx* iso, SpriteSheet sheet) { - assert(iso); +Sprite gfx2d_make_sprite(Gfx2d* gfx, SpriteSheet sheet) { + assert(gfx); assert(sheet); // TODO: Remove memstack_alloc() and replace it with a same-name macro that // calls memstack_alloc_aligned() with sizeof/alignof. No real point in // having unaligned allocations. SpriteInstance* sprite = memstack_alloc_aligned( - &iso->stack, sizeof(SpriteInstance), alignof(SpriteInstance)); + &gfx->stack, sizeof(SpriteInstance), alignof(SpriteInstance)); sprite->sheet = (const Ss_SpriteSheet*)sheet; - sprite->next = iso->head_sprite; - iso->head_sprite = sprite; + sprite->next = gfx->head_sprite; + gfx->head_sprite = sprite; return (Sprite)sprite; } -void isogfx_set_sprite_position(IsoGfx* iso, Sprite hSprite, int x, int y) { - assert(iso); +void gfx2d_set_sprite_position(Gfx2d* gfx, Sprite hSprite, int x, int y) { + assert(gfx); SpriteInstance* sprite = (SpriteInstance*)hSprite; sprite->position.x = x; sprite->position.y = y; } -void isogfx_set_sprite_animation(IsoGfx* iso, Sprite hSprite, int animation) { - assert(iso); +void gfx2d_set_sprite_animation(Gfx2d* gfx, Sprite hSprite, int animation) { + assert(gfx); SpriteInstance* sprite = (SpriteInstance*)hSprite; sprite->animation = animation; } -void isogfx_update(IsoGfx* iso, double t) { - assert(iso); +void gfx2d_update(Gfx2d* gfx, double t) { + assert(gfx); // If this is the first time update() is called after initialization, just // record the starting animation time. - if (iso->last_animation_time == 0.0) { - iso->last_animation_time = t; + if (gfx->last_animation_time == 0.0) { + gfx->last_animation_time = t; return; } - if ((t - iso->last_animation_time) >= ANIMATION_UPDATE_DELTA) { + if ((t - gfx->last_animation_time) >= ANIMATION_UPDATE_DELTA) { // TODO: Consider linking animated sprites in a separate list so that we // only walk over those here and not also the static sprites. - for (SpriteInstance* sprite = iso->head_sprite; sprite; + for (SpriteInstance* sprite = gfx->head_sprite; sprite; sprite = sprite->next) { const Ss_SpriteSheet* sheet = sprite->sheet; const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation); sprite->frame = (sprite->frame + 1) % row->num_cols; } - iso->last_animation_time = t; + gfx->last_animation_time = t; } } @@ -556,6 +556,7 @@ static void draw_rect( Screen* screen, ivec2 top_left, int rect_width, int rect_height, const Pixel* pixels, const uint8_t* indices) { assert(screen); + assert(pixels); #define rect_pixel(X, Y) \ (indices ? pixels[indices[Y * rect_width + X]] : pixels[Y * rect_width + X]) @@ -584,116 +585,116 @@ static void draw_rect( } /// Draw a tile in an orthogonal map. -static void draw_tile_ortho(IsoGfx* iso, Tile tile, int x, int y) { - assert(iso); - assert(iso->tileset); +static void draw_tile_ortho(Gfx2d* gfx, Tile tile, int x, int y) { + assert(gfx); + assert(gfx->tileset); assert(x >= 0); assert(y >= 0); - assert(x < iso->map->world_width); - assert(y < iso->map->world_height); + assert(x < gfx->map->world_width); + assert(y < gfx->map->world_height); - const Ts_Tile* pTile = ts_tileset_get_tile(iso->tileset, tile); - const Pixel* pixels = ts_tileset_get_tile_pixels(iso->tileset, tile); + const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile); + const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile); const ivec2 screen_origin = map2screen( - iso->camera, iso->map->base_tile_width, iso->map->base_tile_height, x, y); + gfx->camera, gfx->map->base_tile_width, gfx->map->base_tile_height, x, y); draw_rect( - &iso->screen, screen_origin, pTile->width, pTile->height, pixels, + &gfx->screen, screen_origin, pTile->width, pTile->height, pixels, nullptr); } /// Draw a tile in an isometric map. -static void draw_tile_iso(IsoGfx* iso, Tile tile, int iso_x, int iso_y) { - assert(iso); - assert(iso->tileset); +static void draw_tile_iso(Gfx2d* gfx, Tile tile, int iso_x, int iso_y) { + assert(gfx); + assert(gfx->tileset); assert(iso_x >= 0); assert(iso_y >= 0); - assert(iso_x < iso->map->world_width); - assert(iso_y < iso->map->world_height); + assert(iso_x < gfx->map->world_width); + assert(iso_y < gfx->map->world_height); - const Ts_Tile* pTile = ts_tileset_get_tile(iso->tileset, tile); - const Pixel* pixels = ts_tileset_get_tile_pixels(iso->tileset, tile); + const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile); + const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile); // Compute the screen coordinates of the top diamond-corner of the tile (the // base tile for super tiles). // World (0, 0) -> (screen_width / 2, 0). const ivec2 screen_origin = - iso2cart(iso->iso_space, iso->camera, iso_x, iso_y); + iso2cart(gfx->iso_space, gfx->camera, iso_x, iso_y); // Move from the top diamond-corner to the top-left corner of the tile image. // For regular tiles, tile height == base tile height, so the y offset is 0. // For super tiles, move as high up as the height of the tile. const ivec2 offset = { - -(iso->map->base_tile_width / 2), - pTile->height - iso->map->base_tile_height}; + -(gfx->map->base_tile_width / 2), + pTile->height - gfx->map->base_tile_height}; const ivec2 top_left = ivec2_add(screen_origin, offset); draw_rect( - &iso->screen, top_left, pTile->width, pTile->height, pixels, nullptr); + &gfx->screen, top_left, pTile->width, pTile->height, pixels, nullptr); } -static void draw_map_ortho(IsoGfx* iso) { - assert(iso); - assert(iso->map); +static void draw_map_ortho(Gfx2d* gfx) { + assert(gfx); + assert(gfx->map); // TODO: Same TODOs as in draw_map_iso(). - const Tm_Layer* layer = tm_map_get_layer(iso->map, 0); + const Tm_Layer* layer = tm_map_get_layer(gfx->map, 0); - for (int wy = 0; wy < iso->map->world_height; ++wy) { - for (int wx = 0; wx < iso->map->world_width; ++wx) { - const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy); - draw_tile_ortho(iso, tile, wx, wy); + for (int wy = 0; wy < gfx->map->world_height; ++wy) { + for (int wx = 0; wx < gfx->map->world_width; ++wx) { + const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy); + draw_tile_ortho(gfx, tile, wx, wy); } } } -static void draw_map_iso(IsoGfx* iso) { - assert(iso); - assert(iso->map); +static void draw_map_iso(Gfx2d* gfx) { + assert(gfx); + assert(gfx->map); // TODO: Support for multiple layers. - const Tm_Layer* layer = tm_map_get_layer(iso->map, 0); + const Tm_Layer* layer = tm_map_get_layer(gfx->map, 0); // TODO: Culling. // Ex: map the screen corners to tile space to cull. // Ex: walk in screen space and fetch the tile. // The tile-centric approach might be more cache-friendly since the // screen-centric approach would juggle multiple tiles throughout the scan. - for (int wy = 0; wy < iso->map->world_height; ++wy) { - for (int wx = 0; wx < iso->map->world_width; ++wx) { - const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy); - draw_tile_iso(iso, tile, wx, wy); + for (int wy = 0; wy < gfx->map->world_height; ++wy) { + for (int wx = 0; wx < gfx->map->world_width; ++wx) { + const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy); + draw_tile_iso(gfx, tile, wx, wy); } } } -static void draw_map(IsoGfx* iso) { - assert(iso); - assert(iso->map); - assert(iso->screen.pixels); +static void draw_map(Gfx2d* gfx) { + assert(gfx); + assert(gfx->map); + assert(gfx->screen.pixels); - const int W = iso->screen.width; - const int H = iso->screen.height; + const int W = gfx->screen.width; + const int H = gfx->screen.height; - memset(iso->screen.pixels, 0, W * H * sizeof(Pixel)); + memset(gfx->screen.pixels, 0, W * H * sizeof(Pixel)); - const Tm_Flags* flags = (const Tm_Flags*)&iso->map->flags; + const Tm_Flags* flags = (const Tm_Flags*)&gfx->map->flags; switch (flags->orientation) { case Tm_Orthogonal: - draw_map_ortho(iso); + draw_map_ortho(gfx); break; case Tm_Isometric: - draw_map_iso(iso); + draw_map_iso(gfx); break; } } /// Draw a sprite in an orthogonal/Cartesian coordinate system. static void draw_sprite_ortho( - IsoGfx* iso, const SpriteInstance* sprite, const Ss_SpriteSheet* sheet) { - assert(iso); + Gfx2d* gfx, const SpriteInstance* sprite, const Ss_SpriteSheet* sheet) { + assert(gfx); assert(sprite); assert(sheet); assert(sprite->animation >= 0); @@ -704,20 +705,20 @@ static void draw_sprite_ortho( // -base_tile_width/2 along the x-axis to align the sprite with the leftmost // edge of the tile it is on. const ivec2 screen_origin = map2screen( - iso->camera, iso->map->base_tile_width, iso->map->base_tile_height, + gfx->camera, gfx->map->base_tile_width, gfx->map->base_tile_height, sprite->position.x, sprite->position.y); const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation); const uint8_t* frame = ss_get_sprite_sheet_sprite(sheet, row, sprite->frame); draw_rect( - &iso->screen, screen_origin, sheet->sprite_width, sheet->sprite_height, + &gfx->screen, screen_origin, sheet->sprite_width, sheet->sprite_height, sheet->palette.colours, frame); } /// Draw a sprite in an isometric coordinate system. static void draw_sprite_iso( - IsoGfx* iso, const SpriteInstance* sprite, const Ss_SpriteSheet* sheet) { - assert(iso); + Gfx2d* gfx, const SpriteInstance* sprite, const Ss_SpriteSheet* sheet) { + assert(gfx); assert(sprite); assert(sheet); assert(sprite->animation >= 0); @@ -728,92 +729,92 @@ static void draw_sprite_iso( // -base_tile_width/2 along the x-axis to align the sprite with the leftmost // edge of the tile it is on. const ivec2 screen_origin = iso2cart( - iso->iso_space, iso->camera, sprite->position.x, sprite->position.y); - const ivec2 offset = {-(iso->map->base_tile_width / 2), 0}; + gfx->iso_space, gfx->camera, sprite->position.x, sprite->position.y); + const ivec2 offset = {-(gfx->map->base_tile_width / 2), 0}; const ivec2 top_left = ivec2_add(screen_origin, offset); const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation); const uint8_t* frame = ss_get_sprite_sheet_sprite(sheet, row, sprite->frame); draw_rect( - &iso->screen, top_left, sheet->sprite_width, sheet->sprite_height, + &gfx->screen, top_left, sheet->sprite_width, sheet->sprite_height, sheet->palette.colours, frame); } -static void draw_sprites(IsoGfx* iso) { - assert(iso); - assert(iso->map); +static void draw_sprites(Gfx2d* gfx) { + assert(gfx); + assert(gfx->map); - const Tm_Flags* flags = (const Tm_Flags*)&iso->map->flags; + const Tm_Flags* flags = (const Tm_Flags*)&gfx->map->flags; switch (flags->orientation) { case Tm_Orthogonal: - for (const SpriteInstance* sprite = iso->head_sprite; sprite; + for (const SpriteInstance* sprite = gfx->head_sprite; sprite; sprite = sprite->next) { - draw_sprite_ortho(iso, sprite, sprite->sheet); + draw_sprite_ortho(gfx, sprite, sprite->sheet); } break; case Tm_Isometric: - for (const SpriteInstance* sprite = iso->head_sprite; sprite; + for (const SpriteInstance* sprite = gfx->head_sprite; sprite; sprite = sprite->next) { - draw_sprite_iso(iso, sprite, sprite->sheet); + draw_sprite_iso(gfx, sprite, sprite->sheet); } break; } } -void isogfx_set_camera(IsoGfx* iso, int x, int y) { - assert(iso); - iso->camera = (ivec2){x, y}; +void gfx2d_set_camera(Gfx2d* gfx, int x, int y) { + assert(gfx); + gfx->camera = (ivec2){x, y}; } -void isogfx_render(IsoGfx* iso) { - assert(iso); - draw_map(iso); - draw_sprites(iso); +void gfx2d_render(Gfx2d* gfx) { + assert(gfx); + draw_map(gfx); + draw_sprites(gfx); } -void isogfx_draw_tile(IsoGfx* iso, int x, int y, Tile tile) { - assert(iso); - assert(iso->map); +void gfx2d_draw_tile(Gfx2d* gfx, int x, int y, Tile tile) { + assert(gfx); + assert(gfx->map); - const Tm_Flags* flags = (const Tm_Flags*)&iso->map->flags; + const Tm_Flags* flags = (const Tm_Flags*)&gfx->map->flags; switch (flags->orientation) { case Tm_Orthogonal: - draw_tile_ortho(iso, tile, x, y); + draw_tile_ortho(gfx, tile, x, y); break; case Tm_Isometric: - draw_tile_iso(iso, tile, x, y); + draw_tile_iso(gfx, tile, x, y); break; } } -void isogfx_get_screen_size(const IsoGfx* iso, int* width, int* height) { - assert(iso); +void gfx2d_get_screen_size(const Gfx2d* gfx, int* width, int* height) { + assert(gfx); assert(width); assert(height); - *width = iso->screen.width; - *height = iso->screen.height; + *width = gfx->screen.width; + *height = gfx->screen.height; } -const Pixel* isogfx_get_screen_buffer(const IsoGfx* iso) { - assert(iso); - return iso->screen.pixels; +const Pixel* gfx2d_get_screen_buffer(const Gfx2d* gfx) { + assert(gfx); + return gfx->screen.pixels; } -void isogfx_pick_tile( - const IsoGfx* iso, double xcart, double ycart, int* xiso, int* yiso) { - assert(iso); +void gfx2d_pick_tile( + const Gfx2d* gfx, double xcart, double ycart, int* xiso, int* yiso) { + assert(gfx); assert(xiso); assert(yiso); - const vec2 camera = ivec2_to_vec2(iso->camera); + const vec2 camera = ivec2_to_vec2(gfx->camera); const vec2 xy_cart = vec2_add(camera, (vec2){xcart, ycart}); const vec2 xy_iso = cart2iso( - xy_cart, iso->map->base_tile_width, iso->map->base_tile_height, - iso->screen.width); + xy_cart, gfx->map->base_tile_width, gfx->map->base_tile_height, + gfx->screen.width); - if ((0 <= xy_iso.x) && (xy_iso.x < iso->map->world_width) && - (0 <= xy_iso.y) && (xy_iso.y < iso->map->world_height)) { + if ((0 <= xy_iso.x) && (xy_iso.x < gfx->map->world_width) && + (0 <= xy_iso.y) && (xy_iso.y < gfx->map->world_height)) { *xiso = (int)xy_iso.x; *yiso = (int)xy_iso.y; } else { -- cgit v1.2.3