diff options
| author | 3gg <3gg@shellblade.net> | 2025-09-04 19:16:32 -0700 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-09-04 19:16:32 -0700 |
| commit | 5294ea7acb86de460e2426a6dac1d281979d0c3b (patch) | |
| tree | a93bd0dc61340ea282d01a48f106abc6d787e455 | |
| parent | 17d7532c796eced679e7e234c4e6dc7546045c22 (diff) | |
Rename isogfx -> gfx2d
| -rw-r--r-- | demos/checkerboard/checkerboard.c | 62 | ||||
| -rw-r--r-- | demos/isomap/isomap.c | 50 | ||||
| -rw-r--r-- | include/isogfx/backend.h | 29 | ||||
| -rw-r--r-- | include/isogfx/gfx2d.h | 54 | ||||
| -rw-r--r-- | src/backend.c | 28 | ||||
| -rw-r--r-- | 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 { | |||
| 47 | } Colour; | 47 | } Colour; |
| 48 | 48 | ||
| 49 | typedef struct GfxAppState { | 49 | typedef struct GfxAppState { |
| 50 | IsoBackend* backend; | 50 | Gfx2dBackend* backend; |
| 51 | IsoGfx* iso; | 51 | Gfx2d* gfx; |
| 52 | Tile red; | 52 | Tile red; |
| 53 | int xpick; | 53 | int xpick; |
| 54 | int ypick; | 54 | int ypick; |
| 55 | } GfxAppState; | 55 | } GfxAppState; |
| 56 | 56 | ||
| 57 | static void make_checkerboard(IsoGfx* iso, Tile black, Tile white) { | 57 | static void make_checkerboard(Gfx2d* iso, Tile black, Tile white) { |
| 58 | assert(iso); | 58 | assert(iso); |
| 59 | for (int y = 0; y < isogfx_world_height(iso); ++y) { | 59 | for (int y = 0; y < gfx2d_world_height(iso); ++y) { |
| 60 | for (int x = 0; x < isogfx_world_width(iso); ++x) { | 60 | for (int x = 0; x < gfx2d_world_width(iso); ++x) { |
| 61 | const int odd_col = x & 1; | 61 | const int odd_col = x & 1; |
| 62 | const int odd_row = y & 1; | 62 | const int odd_row = y & 1; |
| 63 | const Tile value = (odd_row ^ odd_col) == 0 ? black : white; | 63 | const Tile value = (odd_row ^ odd_col) == 0 ? black : white; |
| 64 | isogfx_set_tile(iso, x, y, value); | 64 | gfx2d_set_tile(iso, x, y, value); |
| 65 | } | 65 | } |
| 66 | } | 66 | } |
| 67 | } | 67 | } |
| @@ -72,28 +72,28 @@ static bool init(GfxApp* app, GfxAppState* state, int argc, const char** argv) { | |||
| 72 | (void)argc; | 72 | (void)argc; |
| 73 | (void)argv; | 73 | (void)argv; |
| 74 | 74 | ||
| 75 | if (!((state->iso = | 75 | if (!((state->gfx = |
| 76 | isogfx_new(&(IsoGfxDesc){.memory = MEMORY, | 76 | gfx2d_new(&(Gfx2dDesc){.memory = MEMORY, |
| 77 | .memory_size = MEMORY_SIZE, | 77 | .memory_size = MEMORY_SIZE, |
| 78 | .screen_width = SCREEN_WIDTH, | 78 | .screen_width = SCREEN_WIDTH, |
| 79 | .screen_height = SCREEN_HEIGHT})))) { | 79 | .screen_height = SCREEN_HEIGHT})))) { |
| 80 | return false; | 80 | return false; |
| 81 | } | 81 | } |
| 82 | IsoGfx* iso = state->iso; | 82 | Gfx2d* iso = state->gfx; |
| 83 | 83 | ||
| 84 | isogfx_make_map( | 84 | gfx2d_make_map( |
| 85 | iso, &(MapDesc){.tile_width = TILE_WIDTH, | 85 | iso, &(MapDesc){.tile_width = TILE_WIDTH, |
| 86 | .tile_height = TILE_HEIGHT, | 86 | .tile_height = TILE_HEIGHT, |
| 87 | .world_width = WORLD_WIDTH, | 87 | .world_width = WORLD_WIDTH, |
| 88 | .world_height = WORLD_HEIGHT, | 88 | .world_height = WORLD_HEIGHT, |
| 89 | .num_tiles = NUM_TILES}); | 89 | .num_tiles = NUM_TILES}); |
| 90 | 90 | ||
| 91 | const Tile black = isogfx_make_tile(iso, &tile_set[Black]); | 91 | const Tile black = gfx2d_make_tile(iso, &tile_set[Black]); |
| 92 | const Tile white = isogfx_make_tile(iso, &tile_set[White]); | 92 | const Tile white = gfx2d_make_tile(iso, &tile_set[White]); |
| 93 | state->red = isogfx_make_tile(iso, &tile_set[Red]); | 93 | state->red = gfx2d_make_tile(iso, &tile_set[Red]); |
| 94 | make_checkerboard(iso, black, white); | 94 | make_checkerboard(iso, black, white); |
| 95 | 95 | ||
| 96 | if (!((state->backend = iso_backend_init(iso)))) { | 96 | if (!((state->backend = gfx2d_backend_init(iso)))) { |
| 97 | return false; | 97 | return false; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| @@ -104,8 +104,8 @@ static void shutdown(GfxApp* app, GfxAppState* state) { | |||
| 104 | assert(app); | 104 | assert(app); |
| 105 | assert(state); | 105 | assert(state); |
| 106 | 106 | ||
| 107 | iso_backend_shutdown(&state->backend); | 107 | gfx2d_backend_shutdown(&state->backend); |
| 108 | isogfx_del(&state->iso); | 108 | gfx2d_del(&state->gfx); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static void update(GfxApp* app, GfxAppState* state, double t, double dt) { | 111 | 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) { | |||
| 113 | assert(state); | 113 | assert(state); |
| 114 | (void)dt; | 114 | (void)dt; |
| 115 | 115 | ||
| 116 | IsoGfx* iso = state->iso; | 116 | Gfx2d* iso = state->gfx; |
| 117 | 117 | ||
| 118 | isogfx_update(iso, t); | 118 | gfx2d_update(iso, t); |
| 119 | 119 | ||
| 120 | // Get mouse position in window coordinates. | 120 | // Get mouse position in window coordinates. |
| 121 | double mouse_x, mouse_y; | 121 | double mouse_x, mouse_y; |
| 122 | gfx_app_get_mouse_position(app, &mouse_x, &mouse_y); | 122 | gfx_app_get_mouse_position(app, &mouse_x, &mouse_y); |
| 123 | 123 | ||
| 124 | // Map from window coordinates to virtual screen coordinates. | 124 | // Map from window coordinates to virtual screen coordinates. |
| 125 | iso_backend_get_mouse_position( | 125 | gfx2d_backend_get_mouse_position( |
| 126 | state->backend, mouse_x, mouse_y, &mouse_x, &mouse_y); | 126 | state->backend, mouse_x, mouse_y, &mouse_x, &mouse_y); |
| 127 | 127 | ||
| 128 | isogfx_pick_tile(iso, mouse_x, mouse_y, &state->xpick, &state->ypick); | 128 | gfx2d_pick_tile(iso, mouse_x, mouse_y, &state->xpick, &state->ypick); |
| 129 | 129 | ||
| 130 | printf("Picked tile: (%d, %d)\n", state->xpick, state->ypick); | 130 | printf("Picked tile: (%d, %d)\n", state->xpick, state->ypick); |
| 131 | } | 131 | } |
| @@ -134,22 +134,22 @@ static void render(const GfxApp* app, GfxAppState* state) { | |||
| 134 | assert(app); | 134 | assert(app); |
| 135 | assert(state); | 135 | assert(state); |
| 136 | 136 | ||
| 137 | IsoGfx* iso = state->iso; | 137 | Gfx2d* iso = state->gfx; |
| 138 | 138 | ||
| 139 | isogfx_render(iso); | 139 | gfx2d_render(iso); |
| 140 | 140 | ||
| 141 | if ((state->xpick != -1) && (state->ypick != -1)) { | 141 | if ((state->xpick != -1) && (state->ypick != -1)) { |
| 142 | isogfx_draw_tile(iso, state->xpick, state->ypick, state->red); | 142 | gfx2d_draw_tile(iso, state->xpick, state->ypick, state->red); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | iso_backend_render(state->backend, iso); | 145 | gfx2d_backend_render(state->backend, iso); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | static void resize(GfxApp* app, GfxAppState* state, int width, int height) { | 148 | static void resize(GfxApp* app, GfxAppState* state, int width, int height) { |
| 149 | assert(app); | 149 | assert(app); |
| 150 | assert(state); | 150 | assert(state); |
| 151 | 151 | ||
| 152 | iso_backend_resize_window(state->backend, state->iso, width, height); | 152 | gfx2d_backend_resize_window(state->backend, state->gfx, width, height); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | int main(int argc, const char** argv) { | 155 | 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; | |||
| 22 | uint8_t MEMORY[MEMORY_SIZE]; | 22 | uint8_t MEMORY[MEMORY_SIZE]; |
| 23 | 23 | ||
| 24 | typedef struct GfxAppState { | 24 | typedef struct GfxAppState { |
| 25 | IsoBackend* backend; | 25 | Gfx2dBackend* backend; |
| 26 | IsoGfx* iso; | 26 | Gfx2d* gfx; |
| 27 | int xpick; | 27 | int xpick; |
| 28 | int ypick; | 28 | int ypick; |
| 29 | vec2 camera; | 29 | vec2 camera; |
| 30 | SpriteSheet stag_sheet; | 30 | SpriteSheet stag_sheet; |
| 31 | Sprite stag; | 31 | Sprite stag; |
| 32 | } GfxAppState; | 32 | } GfxAppState; |
| 33 | 33 | ||
| 34 | static bool init(GfxApp* app, GfxAppState* state, int argc, const char** argv) { | 34 | 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) { | |||
| 37 | (void)argc; | 37 | (void)argc; |
| 38 | (void)argv; | 38 | (void)argv; |
| 39 | 39 | ||
| 40 | if (!((state->iso = | 40 | if (!((state->gfx = |
| 41 | isogfx_new(&(IsoGfxDesc){.memory = MEMORY, | 41 | gfx2d_new(&(Gfx2dDesc){.memory = MEMORY, |
| 42 | .memory_size = MEMORY_SIZE, | 42 | .memory_size = MEMORY_SIZE, |
| 43 | .screen_width = SCREEN_WIDTH, | 43 | .screen_width = SCREEN_WIDTH, |
| 44 | .screen_height = SCREEN_HEIGHT})))) { | 44 | .screen_height = SCREEN_HEIGHT})))) { |
| 45 | return false; | 45 | return false; |
| 46 | } | 46 | } |
| 47 | IsoGfx* iso = state->iso; | 47 | Gfx2d* iso = state->gfx; |
| 48 | 48 | ||
| 49 | if (!isogfx_load_map( | 49 | if (!gfx2d_load_map( |
| 50 | iso, "/home/jeanne/Nextcloud/assets/tilemaps/scrabling1.tm")) { | 50 | iso, "/home/jeanne/Nextcloud/assets/tilemaps/scrabling1.tm")) { |
| 51 | return false; | 51 | return false; |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | if (!((state->stag_sheet = isogfx_load_sprite_sheet( | 54 | if (!((state->stag_sheet = gfx2d_load_sprite_sheet( |
| 55 | iso, | 55 | iso, |
| 56 | "/home/jeanne/Nextcloud/assets/tilesets/scrabling/critters/stag/" | 56 | "/home/jeanne/Nextcloud/assets/tilesets/scrabling/critters/stag/" |
| 57 | "stag.ss")))) { | 57 | "stag.ss")))) { |
| 58 | return false; | 58 | return false; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | state->stag = isogfx_make_sprite(iso, state->stag_sheet); | 61 | state->stag = gfx2d_make_sprite(iso, state->stag_sheet); |
| 62 | isogfx_set_sprite_position(iso, state->stag, 0, 0); | 62 | gfx2d_set_sprite_position(iso, state->stag, 0, 0); |
| 63 | 63 | ||
| 64 | if (!((state->backend = iso_backend_init(iso)))) { | 64 | if (!((state->backend = gfx2d_backend_init(iso)))) { |
| 65 | return false; | 65 | return false; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| @@ -101,25 +101,25 @@ static void update(GfxApp* app, GfxAppState* state, double t, double dt) { | |||
| 101 | 101 | ||
| 102 | state->camera = vec2_add(state->camera, get_camera_movement(app, (R)dt)); | 102 | state->camera = vec2_add(state->camera, get_camera_movement(app, (R)dt)); |
| 103 | 103 | ||
| 104 | IsoGfx* iso = state->iso; | 104 | Gfx2d* iso = state->gfx; |
| 105 | isogfx_set_camera(iso, (int)state->camera.x, (int)state->camera.y); | 105 | gfx2d_set_camera(iso, (int)state->camera.x, (int)state->camera.y); |
| 106 | isogfx_update(iso, t); | 106 | gfx2d_update(iso, t); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static void render(const GfxApp* app, GfxAppState* state) { | 109 | static void render(const GfxApp* app, GfxAppState* state) { |
| 110 | assert(app); | 110 | assert(app); |
| 111 | assert(state); | 111 | assert(state); |
| 112 | 112 | ||
| 113 | IsoGfx* iso = state->iso; | 113 | Gfx2d* iso = state->gfx; |
| 114 | isogfx_render(iso); | 114 | gfx2d_render(iso); |
| 115 | iso_backend_render(state->backend, iso); | 115 | gfx2d_backend_render(state->backend, iso); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | static void resize(GfxApp* app, GfxAppState* state, int width, int height) { | 118 | static void resize(GfxApp* app, GfxAppState* state, int width, int height) { |
| 119 | assert(app); | 119 | assert(app); |
| 120 | assert(state); | 120 | assert(state); |
| 121 | 121 | ||
| 122 | iso_backend_resize_window(state->backend, state->iso, width, height); | 122 | gfx2d_backend_resize_window(state->backend, state->gfx, width, height); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | int main(int argc, const char** argv) { | 125 | 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 @@ | |||
| 2 | 2 | ||
| 3 | #include <stdbool.h> | 3 | #include <stdbool.h> |
| 4 | 4 | ||
| 5 | typedef struct Gfx Gfx; | 5 | typedef struct Gfx Gfx; |
| 6 | typedef struct IsoGfx IsoGfx; | 6 | typedef struct Gfx2d Gfx2d; |
| 7 | 7 | ||
| 8 | typedef struct IsoBackend IsoBackend; | 8 | typedef struct Gfx2dBackend Gfx2dBackend; |
| 9 | 9 | ||
| 10 | /// Initialize the backend. | 10 | /// Initialize the backend. |
| 11 | IsoBackend* iso_backend_init(const IsoGfx*); | 11 | Gfx2dBackend* gfx2d_backend_init(const Gfx2d*); |
| 12 | 12 | ||
| 13 | /// Shut down the backend. | 13 | /// Shut down the backend. |
| 14 | void iso_backend_shutdown(IsoBackend**); | 14 | void gfx2d_backend_shutdown(Gfx2dBackend**); |
| 15 | 15 | ||
| 16 | /// Notify the backend of a window resize event. | 16 | /// Notify the backend of a window resize event. |
| 17 | /// This allows the backend to determine how to position and scale the iso | 17 | /// This allows the backend to determine how to position and scale the gfx |
| 18 | /// screen buffer on the graphics window. | 18 | /// screen buffer on the graphics window. |
| 19 | void iso_backend_resize_window( | 19 | void gfx2d_backend_resize_window( |
| 20 | IsoBackend*, const IsoGfx*, int width, int height); | 20 | Gfx2dBackend*, const Gfx2d*, int width, int height); |
| 21 | 21 | ||
| 22 | /// Render the iso screen to the graphics window. | 22 | /// Render the gfx screen to the graphics window. |
| 23 | void iso_backend_render(const IsoBackend*, const IsoGfx*); | 23 | void gfx2d_backend_render(const Gfx2dBackend*, const Gfx2d*); |
| 24 | 24 | ||
| 25 | /// Map window coordinates to iso space coordinates. | 25 | /// Map window coordinates to gfx space coordinates. |
| 26 | /// This takes into account any possible resizing done by the backend in | 26 | /// This takes into account any possible resizing done by the backend in |
| 27 | /// response to calls to iso_backend_resize_window(). | 27 | /// response to calls to gfx2d_backend_resize_window(). |
| 28 | bool iso_backend_get_mouse_position( | 28 | bool gfx2d_backend_get_mouse_position( |
| 29 | const IsoBackend*, double window_x, double window_y, double* x, double* y); | 29 | const Gfx2dBackend*, double window_x, double window_y, double* x, |
| 30 | 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 @@ | |||
| 8 | #include <stddef.h> | 8 | #include <stddef.h> |
| 9 | #include <stdint.h> | 9 | #include <stdint.h> |
| 10 | 10 | ||
| 11 | typedef struct IsoGfx IsoGfx; | 11 | typedef struct Gfx2d Gfx2d; |
| 12 | 12 | ||
| 13 | /// Sprite sheet handle. | 13 | /// Sprite sheet handle. |
| 14 | typedef uintptr_t SpriteSheet; | 14 | typedef uintptr_t SpriteSheet; |
| @@ -50,43 +50,43 @@ typedef struct IsoGfxDesc { | |||
| 50 | size_t memory_size; // Size of memory block in bytes. | 50 | size_t memory_size; // Size of memory block in bytes. |
| 51 | int screen_width; // Screen width in pixels. | 51 | int screen_width; // Screen width in pixels. |
| 52 | int screen_height; // Screen height in pixels. | 52 | int screen_height; // Screen height in pixels. |
| 53 | } IsoGfxDesc; | 53 | } Gfx2dDesc; |
| 54 | 54 | ||
| 55 | /// Create a new isometric graphics engine. | 55 | /// Create a new isometric graphics engine. |
| 56 | IsoGfx* isogfx_new(const IsoGfxDesc*); | 56 | Gfx2d* gfx2d_new(const Gfx2dDesc*); |
| 57 | 57 | ||
| 58 | /// Destroy the isometric graphics engine. | 58 | /// Destroy the isometric graphics engine. |
| 59 | void isogfx_del(IsoGfx**); | 59 | void gfx2d_del(Gfx2d**); |
| 60 | 60 | ||
| 61 | /// Clear all loaded worlds and sprites. | 61 | /// Clear all loaded worlds and sprites. |
| 62 | void isogfx_clear(IsoGfx*); | 62 | void gfx2d_clear(Gfx2d*); |
| 63 | 63 | ||
| 64 | /// Create an empty map. | 64 | /// Create an empty map. |
| 65 | void isogfx_make_map(IsoGfx*, const MapDesc*); | 65 | void gfx2d_make_map(Gfx2d*, const MapDesc*); |
| 66 | 66 | ||
| 67 | /// Load a tile map (.TM) file. | 67 | /// Load a tile map (.TM) file. |
| 68 | bool isogfx_load_map(IsoGfx*, const char* filepath); | 68 | bool gfx2d_load_map(Gfx2d*, const char* filepath); |
| 69 | 69 | ||
| 70 | /// Return the world's width. | 70 | /// Return the world's width. |
| 71 | int isogfx_world_width(const IsoGfx*); | 71 | int gfx2d_world_width(const Gfx2d*); |
| 72 | 72 | ||
| 73 | /// Return the world's height. | 73 | /// Return the world's height. |
| 74 | int isogfx_world_height(const IsoGfx*); | 74 | int gfx2d_world_height(const Gfx2d*); |
| 75 | 75 | ||
| 76 | /// Create a new tile. | 76 | /// Create a new tile. |
| 77 | Tile isogfx_make_tile(IsoGfx*, const TileDesc*); | 77 | Tile gfx2d_make_tile(Gfx2d*, const TileDesc*); |
| 78 | 78 | ||
| 79 | /// Set the tile at position (x,y). | 79 | /// Set the tile at position (x,y). |
| 80 | void isogfx_set_tile(IsoGfx*, int x, int y, Tile); | 80 | void gfx2d_set_tile(Gfx2d*, int x, int y, Tile); |
| 81 | 81 | ||
| 82 | /// Set the tiles in positions in the range (x0,y0) - (x1,y1). | 82 | /// Set the tiles in positions in the range (x0,y0) - (x1,y1). |
| 83 | void isogfx_set_tiles(IsoGfx*, int x0, int y0, int x1, int y1, Tile); | 83 | void gfx2d_set_tiles(Gfx2d*, int x0, int y0, int x1, int y1, Tile); |
| 84 | 84 | ||
| 85 | /// Load a sprite sheet (.SS) file. | 85 | /// Load a sprite sheet (.SS) file. |
| 86 | SpriteSheet isogfx_load_sprite_sheet(IsoGfx*, const char* filepath); | 86 | SpriteSheet gfx2d_load_sprite_sheet(Gfx2d*, const char* filepath); |
| 87 | 87 | ||
| 88 | /// Create an animated sprite. | 88 | /// Create an animated sprite. |
| 89 | Sprite isogfx_make_sprite(IsoGfx*, SpriteSheet); | 89 | Sprite gfx2d_make_sprite(Gfx2d*, SpriteSheet); |
| 90 | 90 | ||
| 91 | // TODO: Add a function to delete a sprite. Making the caller manage and re-use | 91 | // TODO: Add a function to delete a sprite. Making the caller manage and re-use |
| 92 | // sprites is a shitty API. | 92 | // sprites is a shitty API. |
| @@ -94,41 +94,41 @@ Sprite isogfx_make_sprite(IsoGfx*, SpriteSheet); | |||
| 94 | // list of sprites so that we can re-use the ones that have been "freed". | 94 | // list of sprites so that we can re-use the ones that have been "freed". |
| 95 | 95 | ||
| 96 | /// Set the sprite's position. | 96 | /// Set the sprite's position. |
| 97 | void isogfx_set_sprite_position(IsoGfx*, Sprite, int x, int y); | 97 | void gfx2d_set_sprite_position(Gfx2d*, Sprite, int x, int y); |
| 98 | 98 | ||
| 99 | /// Set the sprite's current animation. | 99 | /// Set the sprite's current animation. |
| 100 | void isogfx_set_sprite_animation(IsoGfx*, Sprite, int animation); | 100 | void gfx2d_set_sprite_animation(Gfx2d*, Sprite, int animation); |
| 101 | 101 | ||
| 102 | /// Update the renderer. | 102 | /// Update the renderer. |
| 103 | /// | 103 | /// |
| 104 | /// Currently, this updates the sprite animations. | 104 | /// Currently, this updates the sprite animations. |
| 105 | void isogfx_update(IsoGfx*, double t); | 105 | void gfx2d_update(Gfx2d*, double t); |
| 106 | 106 | ||
| 107 | // TODO: Do we really need to store the camera in the library? It's not used | 107 | // TODO: Do we really need to store the camera in the library? It's not used |
| 108 | // for anything other than to render, so we could remove library state and | 108 | // for anything other than to render, so we could remove library state and |
| 109 | // take a camera argument in render() instead. | 109 | // take a camera argument in render() instead. |
| 110 | 110 | ||
| 111 | /// Set the camera. | 111 | /// Set the camera. |
| 112 | void isogfx_set_camera(IsoGfx*, int x, int y); | 112 | void gfx2d_set_camera(Gfx2d*, int x, int y); |
| 113 | 113 | ||
| 114 | /// Render the world. | 114 | /// Render the world. |
| 115 | void isogfx_render(IsoGfx*); | 115 | void gfx2d_render(Gfx2d*); |
| 116 | 116 | ||
| 117 | /// Draw/overlay a tile at position (x,y). | 117 | /// Draw/overlay a tile at position (x,y). |
| 118 | /// | 118 | /// |
| 119 | /// This function just renders a tile at position (x,y) and should be called | 119 | /// This function just renders a tile at position (x,y) and should be called |
| 120 | /// after isogfx_render() to obtain the correct result. To set the tile at | 120 | /// after gfx2d_render() to obtain the correct result. To set the tile at |
| 121 | /// position (x,y) instead, use isogfx_set_tile(). | 121 | /// position (x,y) instead, use gfx2d_set_tile(). |
| 122 | void isogfx_draw_tile(IsoGfx*, int x, int y, Tile); | 122 | void gfx2d_draw_tile(Gfx2d*, int x, int y, Tile); |
| 123 | 123 | ||
| 124 | /// Get the virtual screen's dimensions. | 124 | /// Get the virtual screen's dimensions. |
| 125 | void isogfx_get_screen_size(const IsoGfx*, int* width, int* height); | 125 | void gfx2d_get_screen_size(const Gfx2d*, int* width, int* height); |
| 126 | 126 | ||
| 127 | /// Return a pointer to the virtual screen's colour buffer. | 127 | /// Return a pointer to the virtual screen's colour buffer. |
| 128 | /// | 128 | /// |
| 129 | /// Call after each call to isogfx_render() to retrieve the render output. | 129 | /// Call after each call to gfx2d_render() to retrieve the render output. |
| 130 | const Pixel* isogfx_get_screen_buffer(const IsoGfx*); | 130 | const Pixel* gfx2d_get_screen_buffer(const Gfx2d*); |
| 131 | 131 | ||
| 132 | /// Translate Cartesian to isometric coordinates. | 132 | /// Translate Cartesian to isometric coordinates. |
| 133 | void isogfx_pick_tile( | 133 | void gfx2d_pick_tile( |
| 134 | const IsoGfx*, double xcart, double ycart, int* xiso, int* yiso); | 134 | 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 @@ | |||
| 13 | #include <assert.h> | 13 | #include <assert.h> |
| 14 | #include <stdlib.h> | 14 | #include <stdlib.h> |
| 15 | 15 | ||
| 16 | typedef struct IsoBackend { | 16 | typedef struct Gfx2dBackend { |
| 17 | Gfx* gfx; | 17 | Gfx* gfx; |
| 18 | Mesh* quad_mesh; | 18 | Mesh* quad_mesh; |
| 19 | /// The screen or "iso screen" refers to the colour buffer of the iso graphics | 19 | /// The screen or "iso screen" refers to the colour buffer of the iso graphics |
| @@ -29,12 +29,12 @@ typedef struct IsoBackend { | |||
| 29 | int viewport_x, viewport_y, viewport_width, viewport_height; | 29 | int viewport_x, viewport_y, viewport_width, viewport_height; |
| 30 | double stretch; // Stretch factor from iso screen dimensions to viewport | 30 | double stretch; // Stretch factor from iso screen dimensions to viewport |
| 31 | // dimensions. | 31 | // dimensions. |
| 32 | } IsoBackend; | 32 | } Gfx2dBackend; |
| 33 | 33 | ||
| 34 | IsoBackend* iso_backend_init(const IsoGfx* iso) { | 34 | Gfx2dBackend* gfx2d_backend_init(const Gfx2d* iso) { |
| 35 | assert(iso); | 35 | assert(iso); |
| 36 | 36 | ||
| 37 | IsoBackend* backend = calloc(1, sizeof(IsoBackend)); | 37 | Gfx2dBackend* backend = calloc(1, sizeof(Gfx2dBackend)); |
| 38 | if (!backend) { | 38 | if (!backend) { |
| 39 | return nullptr; | 39 | return nullptr; |
| 40 | } | 40 | } |
| @@ -45,7 +45,7 @@ IsoBackend* iso_backend_init(const IsoGfx* iso) { | |||
| 45 | GfxCore* gfxcore = gfx_get_core(backend->gfx); | 45 | GfxCore* gfxcore = gfx_get_core(backend->gfx); |
| 46 | 46 | ||
| 47 | int screen_width, screen_height; | 47 | int screen_width, screen_height; |
| 48 | isogfx_get_screen_size(iso, &screen_width, &screen_height); | 48 | gfx2d_get_screen_size(iso, &screen_width, &screen_height); |
| 49 | 49 | ||
| 50 | if (!((backend->screen_texture = gfx_make_texture( | 50 | if (!((backend->screen_texture = gfx_make_texture( |
| 51 | gfxcore, &(TextureDesc){.width = screen_width, | 51 | gfxcore, &(TextureDesc){.width = screen_width, |
| @@ -95,10 +95,10 @@ cleanup: | |||
| 95 | return nullptr; | 95 | return nullptr; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | void iso_backend_shutdown(IsoBackend** ppApp) { | 98 | void gfx2d_backend_shutdown(Gfx2dBackend** ppApp) { |
| 99 | assert(ppApp); | 99 | assert(ppApp); |
| 100 | 100 | ||
| 101 | IsoBackend* app = *ppApp; | 101 | Gfx2dBackend* app = *ppApp; |
| 102 | if (!app) { | 102 | if (!app) { |
| 103 | return; | 103 | return; |
| 104 | } | 104 | } |
| @@ -106,8 +106,8 @@ void iso_backend_shutdown(IsoBackend** ppApp) { | |||
| 106 | gfx_destroy(&app->gfx); | 106 | gfx_destroy(&app->gfx); |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | void iso_backend_resize_window( | 109 | void gfx2d_backend_resize_window( |
| 110 | IsoBackend* app, const IsoGfx* iso, int width, int height) { | 110 | Gfx2dBackend* app, const Gfx2d* iso, int width, int height) { |
| 111 | assert(app); | 111 | assert(app); |
| 112 | assert(iso); | 112 | assert(iso); |
| 113 | 113 | ||
| @@ -116,7 +116,7 @@ void iso_backend_resize_window( | |||
| 116 | 116 | ||
| 117 | // Virtual screen dimensions. | 117 | // Virtual screen dimensions. |
| 118 | int screen_width, screen_height; | 118 | int screen_width, screen_height; |
| 119 | isogfx_get_screen_size(iso, &screen_width, &screen_height); | 119 | gfx2d_get_screen_size(iso, &screen_width, &screen_height); |
| 120 | 120 | ||
| 121 | // Stretch the virtual screen onto the viewport while respecting the screen's | 121 | // Stretch the virtual screen onto the viewport while respecting the screen's |
| 122 | // aspect ratio to prevent distortion. | 122 | // aspect ratio to prevent distortion. |
| @@ -135,11 +135,11 @@ void iso_backend_resize_window( | |||
| 135 | } | 135 | } |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | void iso_backend_render(const IsoBackend* app, const IsoGfx* iso) { | 138 | void gfx2d_backend_render(const Gfx2dBackend* app, const Gfx2d* iso) { |
| 139 | assert(app); | 139 | assert(app); |
| 140 | assert(iso); | 140 | assert(iso); |
| 141 | 141 | ||
| 142 | const Pixel* screen = isogfx_get_screen_buffer(iso); | 142 | const Pixel* screen = gfx2d_get_screen_buffer(iso); |
| 143 | assert(screen); | 143 | assert(screen); |
| 144 | gfx_update_texture(app->screen_texture, &(TextureDataDesc){.pixels = screen}); | 144 | gfx_update_texture(app->screen_texture, &(TextureDataDesc){.pixels = screen}); |
| 145 | 145 | ||
| @@ -162,8 +162,8 @@ void iso_backend_render(const IsoBackend* app, const IsoGfx* iso) { | |||
| 162 | gfx_end_frame(gfxcore); | 162 | gfx_end_frame(gfxcore); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | bool iso_backend_get_mouse_position( | 165 | bool gfx2d_backend_get_mouse_position( |
| 166 | const IsoBackend* app, double window_x, double window_y, double* x, | 166 | const Gfx2dBackend* app, double window_x, double window_y, double* x, |
| 167 | double* y) { | 167 | double* y) { |
| 168 | assert(app); | 168 | assert(app); |
| 169 | 169 | ||
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 { | |||
| 32 | // Renderer state. | 32 | // Renderer state. |
| 33 | // ----------------------------------------------------------------------------- | 33 | // ----------------------------------------------------------------------------- |
| 34 | 34 | ||
| 35 | typedef struct CoordSystem { | 35 | typedef struct IsoCoordSystem { |
| 36 | ivec2 o; // Origin. | 36 | ivec2 o; // Origin. |
| 37 | ivec2 x; | 37 | ivec2 x; |
| 38 | ivec2 y; | 38 | ivec2 y; |
| 39 | } CoordSystem; | 39 | } IsoCoordSystem; |
| 40 | 40 | ||
| 41 | typedef struct Screen { | 41 | typedef struct Screen { |
| 42 | int width; | 42 | int width; |
| @@ -52,9 +52,9 @@ typedef struct SpriteInstance { | |||
| 52 | int frame; // Current frame of animation. | 52 | int frame; // Current frame of animation. |
| 53 | } SpriteInstance; | 53 | } SpriteInstance; |
| 54 | 54 | ||
| 55 | typedef struct IsoGfx { | 55 | typedef struct Gfx2d { |
| 56 | Screen screen; | 56 | Screen screen; |
| 57 | CoordSystem iso_space; | 57 | IsoCoordSystem iso_space; |
| 58 | ivec2 camera; | 58 | ivec2 camera; |
| 59 | double last_animation_time; | 59 | double last_animation_time; |
| 60 | Tile next_tile; // For procedurally-generated tiles. | 60 | Tile next_tile; // For procedurally-generated tiles. |
| @@ -63,7 +63,7 @@ typedef struct IsoGfx { | |||
| 63 | SpriteInstance* head_sprite; // Head of sprites list. | 63 | SpriteInstance* head_sprite; // Head of sprites list. |
| 64 | memstack stack; | 64 | memstack stack; |
| 65 | size_t watermark; | 65 | size_t watermark; |
| 66 | } IsoGfx; | 66 | } Gfx2d; |
| 67 | 67 | ||
| 68 | // ----------------------------------------------------------------------------- | 68 | // ----------------------------------------------------------------------------- |
| 69 | // Math and world / tile / screen access. | 69 | // Math and world / tile / screen access. |
| @@ -102,7 +102,7 @@ static ivec2 map2screen( | |||
| 102 | 102 | ||
| 103 | /// Create the basis for the isometric coordinate system with origin and vectors | 103 | /// Create the basis for the isometric coordinate system with origin and vectors |
| 104 | /// expressed in the Cartesian system. | 104 | /// expressed in the Cartesian system. |
| 105 | static CoordSystem make_iso_coord_system( | 105 | static IsoCoordSystem make_iso_coord_system( |
| 106 | const Tm_Map* const map, const Screen* const screen) { | 106 | const Tm_Map* const map, const Screen* const screen) { |
| 107 | assert(map); | 107 | assert(map); |
| 108 | assert(screen); | 108 | assert(screen); |
| @@ -111,7 +111,7 @@ static CoordSystem make_iso_coord_system( | |||
| 111 | .x = map->base_tile_width / 2, .y = map->base_tile_height / 2}; | 111 | .x = map->base_tile_width / 2, .y = map->base_tile_height / 2}; |
| 112 | const ivec2 y = { | 112 | const ivec2 y = { |
| 113 | .x = -map->base_tile_width / 2, .y = map->base_tile_height / 2}; | 113 | .x = -map->base_tile_width / 2, .y = map->base_tile_height / 2}; |
| 114 | return (CoordSystem){o, x, y}; | 114 | return (IsoCoordSystem){o, x, y}; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | /// Map isometric coordinates to Cartesian coordinates. | 117 | /// Map isometric coordinates to Cartesian coordinates. |
| @@ -121,7 +121,7 @@ static CoordSystem make_iso_coord_system( | |||
| 121 | /// | 121 | /// |
| 122 | /// Takes the camera displacement into account. | 122 | /// Takes the camera displacement into account. |
| 123 | static ivec2 iso2cart( | 123 | static ivec2 iso2cart( |
| 124 | const CoordSystem iso_space, ivec2 camera, int iso_x, int iso_y) { | 124 | const IsoCoordSystem iso_space, ivec2 camera, int iso_x, int iso_y) { |
| 125 | const ivec2 vx_offset = ivec2_scale(iso_space.x, iso_x); | 125 | const ivec2 vx_offset = ivec2_scale(iso_space.x, iso_x); |
| 126 | const ivec2 vy_offset = ivec2_scale(iso_space.y, iso_y); | 126 | const ivec2 vy_offset = ivec2_scale(iso_space.y, iso_y); |
| 127 | const ivec2 origin_world_space = | 127 | const ivec2 origin_world_space = |
| @@ -170,63 +170,63 @@ static inline Pixel* screen_xy_mut(Screen* screen, int x, int y) { | |||
| 170 | // Renderer, world and tile management. | 170 | // Renderer, world and tile management. |
| 171 | // ----------------------------------------------------------------------------- | 171 | // ----------------------------------------------------------------------------- |
| 172 | 172 | ||
| 173 | IsoGfx* isogfx_new(const IsoGfxDesc* desc) { | 173 | Gfx2d* gfx2d_new(const Gfx2dDesc* desc) { |
| 174 | assert(desc->screen_width > 0); | 174 | assert(desc->screen_width > 0); |
| 175 | assert(desc->screen_height > 0); | 175 | assert(desc->screen_height > 0); |
| 176 | // Part of our implementation assumes even widths and heights for precision. | 176 | // Part of our implementation assumes even widths and heights for precision. |
| 177 | assert((desc->screen_width & 1) == 0); | 177 | assert((desc->screen_width & 1) == 0); |
| 178 | assert((desc->screen_height & 1) == 0); | 178 | assert((desc->screen_height & 1) == 0); |
| 179 | 179 | ||
| 180 | IsoGfx tmp = {0}; | 180 | Gfx2d tmp = {0}; |
| 181 | if (!memstack_make(&tmp.stack, desc->memory_size, desc->memory)) { | 181 | if (!memstack_make(&tmp.stack, desc->memory_size, desc->memory)) { |
| 182 | goto cleanup; | 182 | goto cleanup; |
| 183 | } | 183 | } |
| 184 | IsoGfx* iso = | 184 | Gfx2d* gfx = |
| 185 | memstack_alloc_aligned(&tmp.stack, sizeof(IsoGfx), alignof(IsoGfx)); | 185 | memstack_alloc_aligned(&tmp.stack, sizeof(Gfx2d), alignof(Gfx2d)); |
| 186 | *iso = tmp; | 186 | *gfx = tmp; |
| 187 | 187 | ||
| 188 | const size_t screen_size_bytes = | 188 | const size_t screen_size_bytes = |
| 189 | desc->screen_width * desc->screen_height * sizeof(Pixel); | 189 | desc->screen_width * desc->screen_height * sizeof(Pixel); |
| 190 | Pixel* screen = | 190 | Pixel* screen = |
| 191 | memstack_alloc_aligned(&iso->stack, screen_size_bytes, alignof(Pixel)); | 191 | memstack_alloc_aligned(&gfx->stack, screen_size_bytes, alignof(Pixel)); |
| 192 | 192 | ||
| 193 | iso->screen = (Screen){.width = desc->screen_width, | 193 | gfx->screen = (Screen){.width = desc->screen_width, |
| 194 | .height = desc->screen_height, | 194 | .height = desc->screen_height, |
| 195 | .pixels = screen}; | 195 | .pixels = screen}; |
| 196 | 196 | ||
| 197 | iso->last_animation_time = 0.0; | 197 | gfx->last_animation_time = 0.0; |
| 198 | iso->watermark = memstack_watermark(&iso->stack); | 198 | gfx->watermark = memstack_watermark(&gfx->stack); |
| 199 | 199 | ||
| 200 | return iso; | 200 | return gfx; |
| 201 | 201 | ||
| 202 | cleanup: | 202 | cleanup: |
| 203 | isogfx_del(&iso); | 203 | gfx2d_del(&gfx); |
| 204 | return nullptr; | 204 | return nullptr; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | void isogfx_clear(IsoGfx* iso) { | 207 | void gfx2d_clear(Gfx2d* gfx) { |
| 208 | assert(iso); | 208 | assert(gfx); |
| 209 | iso->last_animation_time = 0.0; | 209 | gfx->last_animation_time = 0.0; |
| 210 | iso->next_tile = 0; | 210 | gfx->next_tile = 0; |
| 211 | iso->map = nullptr; | 211 | gfx->map = nullptr; |
| 212 | iso->tileset = nullptr; | 212 | gfx->tileset = nullptr; |
| 213 | iso->head_sprite = nullptr; | 213 | gfx->head_sprite = nullptr; |
| 214 | // The base of the stack contains the IsoGfx and the screen buffer. Make sure | 214 | // The base of the stack contains the Gfx2d and the screen buffer. Make sure |
| 215 | // we don't clear them. | 215 | // we don't clear them. |
| 216 | memstack_set_watermark(&iso->stack, iso->watermark); | 216 | memstack_set_watermark(&gfx->stack, gfx->watermark); |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | void isogfx_del(IsoGfx** ppIso) { | 219 | void gfx2d_del(Gfx2d** ppGfx) { |
| 220 | assert(ppIso); | 220 | assert(ppGfx); |
| 221 | IsoGfx* iso = *ppIso; | 221 | Gfx2d* gfx = *ppGfx; |
| 222 | if (iso) { | 222 | if (gfx) { |
| 223 | memstack_del(&iso->stack); | 223 | memstack_del(&gfx->stack); |
| 224 | *ppIso = nullptr; | 224 | *ppGfx = nullptr; |
| 225 | } | 225 | } |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | void isogfx_make_map(IsoGfx* iso, const MapDesc* desc) { | 228 | void gfx2d_make_map(Gfx2d* gfx, const MapDesc* desc) { |
| 229 | assert(iso); | 229 | assert(gfx); |
| 230 | assert(desc); | 230 | assert(desc); |
| 231 | assert(desc->tile_width > 0); | 231 | assert(desc->tile_width > 0); |
| 232 | assert(desc->tile_height > 0); | 232 | assert(desc->tile_height > 0); |
| @@ -241,7 +241,7 @@ void isogfx_make_map(IsoGfx* iso, const MapDesc* desc) { | |||
| 241 | assert(desc->num_tiles > 0); | 241 | assert(desc->num_tiles > 0); |
| 242 | 242 | ||
| 243 | // Handle recreation by destroying the previous world and sprites. | 243 | // Handle recreation by destroying the previous world and sprites. |
| 244 | isogfx_clear(iso); | 244 | gfx2d_clear(gfx); |
| 245 | 245 | ||
| 246 | const int world_size = desc->world_width * desc->world_height; | 246 | const int world_size = desc->world_width * desc->world_height; |
| 247 | const size_t map_size_bytes = sizeof(Tm_Map) + (world_size * sizeof(Tile)); | 247 | 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) { | |||
| 256 | (desc->num_tiles * sizeof(Ts_Tile)) + | 256 | (desc->num_tiles * sizeof(Ts_Tile)) + |
| 257 | tile_data_size_bytes; | 257 | tile_data_size_bytes; |
| 258 | 258 | ||
| 259 | iso->map = memstack_alloc_aligned(&iso->stack, map_size_bytes, 4); | 259 | gfx->map = memstack_alloc_aligned(&gfx->stack, map_size_bytes, 4); |
| 260 | *iso->map = (Tm_Map){ | 260 | *gfx->map = (Tm_Map){ |
| 261 | .world_width = desc->world_width, | 261 | .world_width = desc->world_width, |
| 262 | .world_height = desc->world_height, | 262 | .world_height = desc->world_height, |
| 263 | .base_tile_width = desc->tile_width, | 263 | .base_tile_width = desc->tile_width, |
| @@ -265,34 +265,34 @@ void isogfx_make_map(IsoGfx* iso, const MapDesc* desc) { | |||
| 265 | .num_layers = 1, | 265 | .num_layers = 1, |
| 266 | }; | 266 | }; |
| 267 | 267 | ||
| 268 | iso->tileset = memstack_alloc_aligned(&iso->stack, tileset_size_bytes, 4); | 268 | gfx->tileset = memstack_alloc_aligned(&gfx->stack, tileset_size_bytes, 4); |
| 269 | *iso->tileset = (Ts_TileSet){ | 269 | *gfx->tileset = (Ts_TileSet){ |
| 270 | .num_tiles = desc->num_tiles, | 270 | .num_tiles = desc->num_tiles, |
| 271 | }; | 271 | }; |
| 272 | 272 | ||
| 273 | iso->iso_space = make_iso_coord_system(iso->map, &iso->screen); | 273 | gfx->iso_space = make_iso_coord_system(gfx->map, &gfx->screen); |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | bool isogfx_load_map(IsoGfx* iso, const char* filepath) { | 276 | bool gfx2d_load_map(Gfx2d* gfx, const char* filepath) { |
| 277 | assert(iso); | 277 | assert(gfx); |
| 278 | assert(filepath); | 278 | assert(filepath); |
| 279 | 279 | ||
| 280 | bool success = false; | 280 | bool success = false; |
| 281 | 281 | ||
| 282 | // Handle recreation by destroying the previous world and sprites. | 282 | // Handle recreation by destroying the previous world and sprites. |
| 283 | isogfx_clear(iso); | 283 | gfx2d_clear(gfx); |
| 284 | 284 | ||
| 285 | // Load the map. | 285 | // Load the map. |
| 286 | printf("Load tile map: %s\n", filepath); | 286 | printf("Load tile map: %s\n", filepath); |
| 287 | WITH_FILE(filepath, { | 287 | WITH_FILE(filepath, { |
| 288 | const size_t map_size = get_file_size_f(file); | 288 | const size_t map_size = get_file_size_f(file); |
| 289 | iso->map = memstack_alloc_aligned(&iso->stack, map_size, 4); | 289 | gfx->map = memstack_alloc_aligned(&gfx->stack, map_size, 4); |
| 290 | success = read_file_f(file, iso->map); | 290 | success = read_file_f(file, gfx->map); |
| 291 | }); | 291 | }); |
| 292 | if (!success) { | 292 | if (!success) { |
| 293 | goto cleanup; | 293 | goto cleanup; |
| 294 | } | 294 | } |
| 295 | Tm_Map* const map = iso->map; | 295 | Tm_Map* const map = gfx->map; |
| 296 | 296 | ||
| 297 | printf("Map orientation: %d\n", ((Tm_Flags*)&map->flags)->orientation); | 297 | printf("Map orientation: %d\n", ((Tm_Flags*)&map->flags)->orientation); |
| 298 | 298 | ||
| @@ -308,39 +308,39 @@ bool isogfx_load_map(IsoGfx* iso, const char* filepath) { | |||
| 308 | printf("Load tile set: %s\n", ts_path_cwd); | 308 | printf("Load tile set: %s\n", ts_path_cwd); |
| 309 | WITH_FILE(ts_path_cwd, { | 309 | WITH_FILE(ts_path_cwd, { |
| 310 | const size_t file_size = get_file_size_f(file); | 310 | const size_t file_size = get_file_size_f(file); |
| 311 | iso->tileset = memstack_alloc_aligned(&iso->stack, file_size, 4); | 311 | gfx->tileset = memstack_alloc_aligned(&gfx->stack, file_size, 4); |
| 312 | success = read_file_f(file, iso->tileset); | 312 | success = read_file_f(file, gfx->tileset); |
| 313 | }); | 313 | }); |
| 314 | if (!success) { | 314 | if (!success) { |
| 315 | // TODO: Log errors using the log library. | 315 | // TODO: Log errors using the log library. |
| 316 | goto cleanup; | 316 | goto cleanup; |
| 317 | } | 317 | } |
| 318 | const Ts_TileSet* const tileset = iso->tileset; | 318 | const Ts_TileSet* const tileset = gfx->tileset; |
| 319 | printf("Loaded tile set (%u tiles): %s\n", tileset->num_tiles, ts_path_cwd); | 319 | printf("Loaded tile set (%u tiles): %s\n", tileset->num_tiles, ts_path_cwd); |
| 320 | 320 | ||
| 321 | // TODO: These assertions on input data should be library runtime errors. | 321 | // TODO: These assertions on input data should be library runtime errors. |
| 322 | assert(ts_validate_tileset(tileset)); | 322 | assert(ts_validate_tileset(tileset)); |
| 323 | assert(tm_validate_map(map, tileset)); | 323 | assert(tm_validate_map(map, tileset)); |
| 324 | 324 | ||
| 325 | iso->iso_space = make_iso_coord_system(iso->map, &iso->screen); | 325 | gfx->iso_space = make_iso_coord_system(gfx->map, &gfx->screen); |
| 326 | 326 | ||
| 327 | success = true; | 327 | success = true; |
| 328 | 328 | ||
| 329 | cleanup: | 329 | cleanup: |
| 330 | if (!success) { | 330 | if (!success) { |
| 331 | isogfx_clear(iso); | 331 | gfx2d_clear(gfx); |
| 332 | } | 332 | } |
| 333 | return success; | 333 | return success; |
| 334 | } | 334 | } |
| 335 | 335 | ||
| 336 | int isogfx_world_width(const IsoGfx* iso) { | 336 | int gfx2d_world_width(const Gfx2d* gfx) { |
| 337 | assert(iso); | 337 | assert(gfx); |
| 338 | return iso->map->world_width; | 338 | return gfx->map->world_width; |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | int isogfx_world_height(const IsoGfx* iso) { | 341 | int gfx2d_world_height(const Gfx2d* gfx) { |
| 342 | assert(iso); | 342 | assert(gfx); |
| 343 | return iso->map->world_height; | 343 | return gfx->map->world_height; |
| 344 | } | 344 | } |
| 345 | 345 | ||
| 346 | static void make_tile_from_colour( | 346 | static void make_tile_from_colour( |
| @@ -368,19 +368,19 @@ static void make_tile_from_colour( | |||
| 368 | } | 368 | } |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | Tile isogfx_make_tile(IsoGfx* iso, const TileDesc* desc) { | 371 | Tile gfx2d_make_tile(Gfx2d* gfx, const TileDesc* desc) { |
| 372 | assert(iso); | 372 | assert(gfx); |
| 373 | assert(desc); | 373 | assert(desc); |
| 374 | // Client must create a world first. | 374 | // Client must create a world first. |
| 375 | assert(iso->map); | 375 | assert(gfx->map); |
| 376 | assert(iso->tileset); | 376 | assert(gfx->tileset); |
| 377 | // Currently, procedural tiles must match the base tile size. | 377 | // Currently, procedural tiles must match the base tile size. |
| 378 | assert(desc->width == iso->map->base_tile_width); | 378 | assert(desc->width == gfx->map->base_tile_width); |
| 379 | assert(desc->height == iso->map->base_tile_height); | 379 | assert(desc->height == gfx->map->base_tile_height); |
| 380 | // Cannot exceed max tiles. | 380 | // Cannot exceed max tiles. |
| 381 | assert(iso->next_tile < iso->tileset->num_tiles); | 381 | assert(gfx->next_tile < gfx->tileset->num_tiles); |
| 382 | 382 | ||
| 383 | const Tile tile = iso->next_tile++; | 383 | const Tile tile = gfx->next_tile++; |
| 384 | 384 | ||
| 385 | const size_t tile_size_bytes = desc->width * desc->height * sizeof(Pixel); | 385 | const size_t tile_size_bytes = desc->width * desc->height * sizeof(Pixel); |
| 386 | 386 | ||
| @@ -389,16 +389,16 @@ Tile isogfx_make_tile(IsoGfx* iso, const TileDesc* desc) { | |||
| 389 | assert(desc->width > 0); | 389 | assert(desc->width > 0); |
| 390 | assert(desc->height > 0); | 390 | assert(desc->height > 0); |
| 391 | 391 | ||
| 392 | Ts_Tile* const ts_tile = ts_tileset_get_tile_mut(iso->tileset, tile); | 392 | Ts_Tile* const ts_tile = ts_tileset_get_tile_mut(gfx->tileset, tile); |
| 393 | 393 | ||
| 394 | *ts_tile = (Ts_Tile){ | 394 | *ts_tile = (Ts_Tile){ |
| 395 | .width = iso->map->base_tile_width, | 395 | .width = gfx->map->base_tile_width, |
| 396 | .height = iso->map->base_tile_height, | 396 | .height = gfx->map->base_tile_height, |
| 397 | .pixels = tile * tile_size_bytes, | 397 | .pixels = tile * tile_size_bytes, |
| 398 | }; | 398 | }; |
| 399 | 399 | ||
| 400 | Pixel* const tile_pixels = | 400 | Pixel* const tile_pixels = |
| 401 | ts_tileset_get_tile_pixels_mut(iso->tileset, tile); | 401 | ts_tileset_get_tile_pixels_mut(gfx->tileset, tile); |
| 402 | make_tile_from_colour(desc->colour, ts_tile, tile_pixels); | 402 | make_tile_from_colour(desc->colour, ts_tile, tile_pixels); |
| 403 | break; | 403 | break; |
| 404 | } | 404 | } |
| @@ -416,31 +416,31 @@ Tile isogfx_make_tile(IsoGfx* iso, const TileDesc* desc) { | |||
| 416 | return tile; | 416 | return tile; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | void isogfx_set_tile(IsoGfx* iso, int x, int y, Tile tile) { | 419 | void gfx2d_set_tile(Gfx2d* gfx, int x, int y, Tile tile) { |
| 420 | assert(iso); | 420 | assert(gfx); |
| 421 | 421 | ||
| 422 | Tm_Layer* const layer = tm_map_get_layer_mut(iso->map, 0); | 422 | Tm_Layer* const layer = tm_map_get_layer_mut(gfx->map, 0); |
| 423 | Tile* map_tile = tm_layer_get_tile_mut(iso->map, layer, x, y); | 423 | Tile* map_tile = tm_layer_get_tile_mut(gfx->map, layer, x, y); |
| 424 | 424 | ||
| 425 | *map_tile = tile; | 425 | *map_tile = tile; |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | void isogfx_set_tiles(IsoGfx* iso, int x0, int y0, int x1, int y1, Tile tile) { | 428 | void gfx2d_set_tiles(Gfx2d* gfx, int x0, int y0, int x1, int y1, Tile tile) { |
| 429 | assert(iso); | 429 | assert(gfx); |
| 430 | for (int y = y0; y < y1; ++y) { | 430 | for (int y = y0; y < y1; ++y) { |
| 431 | for (int x = x0; x < x1; ++x) { | 431 | for (int x = x0; x < x1; ++x) { |
| 432 | isogfx_set_tile(iso, x, y, tile); | 432 | gfx2d_set_tile(gfx, x, y, tile); |
| 433 | } | 433 | } |
| 434 | } | 434 | } |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | SpriteSheet isogfx_load_sprite_sheet(IsoGfx* iso, const char* filepath) { | 437 | SpriteSheet gfx2d_load_sprite_sheet(Gfx2d* gfx, const char* filepath) { |
| 438 | assert(iso); | 438 | assert(gfx); |
| 439 | assert(filepath); | 439 | assert(filepath); |
| 440 | 440 | ||
| 441 | bool success = false; | 441 | bool success = false; |
| 442 | SpriteSheet spriteSheet = 0; | 442 | SpriteSheet spriteSheet = 0; |
| 443 | const size_t watermark = memstack_watermark(&iso->stack); | 443 | const size_t watermark = memstack_watermark(&gfx->stack); |
| 444 | 444 | ||
| 445 | // Load sprite sheet file. | 445 | // Load sprite sheet file. |
| 446 | printf("Load sprite sheet: %s\n", filepath); | 446 | printf("Load sprite sheet: %s\n", filepath); |
| @@ -448,7 +448,7 @@ SpriteSheet isogfx_load_sprite_sheet(IsoGfx* iso, const char* filepath) { | |||
| 448 | WITH_FILE(filepath, { | 448 | WITH_FILE(filepath, { |
| 449 | const size_t file_size = get_file_size_f(file); | 449 | const size_t file_size = get_file_size_f(file); |
| 450 | ss_sheet = | 450 | ss_sheet = |
| 451 | memstack_alloc_aligned(&iso->stack, file_size, alignof(Ss_SpriteSheet)); | 451 | memstack_alloc_aligned(&gfx->stack, file_size, alignof(Ss_SpriteSheet)); |
| 452 | success = read_file_f(file, ss_sheet); | 452 | success = read_file_f(file, ss_sheet); |
| 453 | }); | 453 | }); |
| 454 | if (!success) { | 454 | if (!success) { |
| @@ -461,63 +461,63 @@ SpriteSheet isogfx_load_sprite_sheet(IsoGfx* iso, const char* filepath) { | |||
| 461 | cleanup: | 461 | cleanup: |
| 462 | if (!success) { | 462 | if (!success) { |
| 463 | if (ss_sheet) { | 463 | if (ss_sheet) { |
| 464 | memstack_set_watermark(&iso->stack, watermark); | 464 | memstack_set_watermark(&gfx->stack, watermark); |
| 465 | } | 465 | } |
| 466 | } | 466 | } |
| 467 | return spriteSheet; | 467 | return spriteSheet; |
| 468 | } | 468 | } |
| 469 | 469 | ||
| 470 | Sprite isogfx_make_sprite(IsoGfx* iso, SpriteSheet sheet) { | 470 | Sprite gfx2d_make_sprite(Gfx2d* gfx, SpriteSheet sheet) { |
| 471 | assert(iso); | 471 | assert(gfx); |
| 472 | assert(sheet); | 472 | assert(sheet); |
| 473 | 473 | ||
| 474 | // TODO: Remove memstack_alloc() and replace it with a same-name macro that | 474 | // TODO: Remove memstack_alloc() and replace it with a same-name macro that |
| 475 | // calls memstack_alloc_aligned() with sizeof/alignof. No real point in | 475 | // calls memstack_alloc_aligned() with sizeof/alignof. No real point in |
| 476 | // having unaligned allocations. | 476 | // having unaligned allocations. |
| 477 | SpriteInstance* sprite = memstack_alloc_aligned( | 477 | SpriteInstance* sprite = memstack_alloc_aligned( |
| 478 | &iso->stack, sizeof(SpriteInstance), alignof(SpriteInstance)); | 478 | &gfx->stack, sizeof(SpriteInstance), alignof(SpriteInstance)); |
| 479 | 479 | ||
| 480 | sprite->sheet = (const Ss_SpriteSheet*)sheet; | 480 | sprite->sheet = (const Ss_SpriteSheet*)sheet; |
| 481 | sprite->next = iso->head_sprite; | 481 | sprite->next = gfx->head_sprite; |
| 482 | iso->head_sprite = sprite; | 482 | gfx->head_sprite = sprite; |
| 483 | 483 | ||
| 484 | return (Sprite)sprite; | 484 | return (Sprite)sprite; |
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | void isogfx_set_sprite_position(IsoGfx* iso, Sprite hSprite, int x, int y) { | 487 | void gfx2d_set_sprite_position(Gfx2d* gfx, Sprite hSprite, int x, int y) { |
| 488 | assert(iso); | 488 | assert(gfx); |
| 489 | SpriteInstance* sprite = (SpriteInstance*)hSprite; | 489 | SpriteInstance* sprite = (SpriteInstance*)hSprite; |
| 490 | sprite->position.x = x; | 490 | sprite->position.x = x; |
| 491 | sprite->position.y = y; | 491 | sprite->position.y = y; |
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | void isogfx_set_sprite_animation(IsoGfx* iso, Sprite hSprite, int animation) { | 494 | void gfx2d_set_sprite_animation(Gfx2d* gfx, Sprite hSprite, int animation) { |
| 495 | assert(iso); | 495 | assert(gfx); |
| 496 | SpriteInstance* sprite = (SpriteInstance*)hSprite; | 496 | SpriteInstance* sprite = (SpriteInstance*)hSprite; |
| 497 | sprite->animation = animation; | 497 | sprite->animation = animation; |
| 498 | } | 498 | } |
| 499 | 499 | ||
| 500 | void isogfx_update(IsoGfx* iso, double t) { | 500 | void gfx2d_update(Gfx2d* gfx, double t) { |
| 501 | assert(iso); | 501 | assert(gfx); |
| 502 | 502 | ||
| 503 | // If this is the first time update() is called after initialization, just | 503 | // If this is the first time update() is called after initialization, just |
| 504 | // record the starting animation time. | 504 | // record the starting animation time. |
| 505 | if (iso->last_animation_time == 0.0) { | 505 | if (gfx->last_animation_time == 0.0) { |
| 506 | iso->last_animation_time = t; | 506 | gfx->last_animation_time = t; |
| 507 | return; | 507 | return; |
| 508 | } | 508 | } |
| 509 | 509 | ||
| 510 | if ((t - iso->last_animation_time) >= ANIMATION_UPDATE_DELTA) { | 510 | if ((t - gfx->last_animation_time) >= ANIMATION_UPDATE_DELTA) { |
| 511 | // TODO: Consider linking animated sprites in a separate list so that we | 511 | // TODO: Consider linking animated sprites in a separate list so that we |
| 512 | // only walk over those here and not also the static sprites. | 512 | // only walk over those here and not also the static sprites. |
| 513 | for (SpriteInstance* sprite = iso->head_sprite; sprite; | 513 | for (SpriteInstance* sprite = gfx->head_sprite; sprite; |
| 514 | sprite = sprite->next) { | 514 | sprite = sprite->next) { |
| 515 | const Ss_SpriteSheet* sheet = sprite->sheet; | 515 | const Ss_SpriteSheet* sheet = sprite->sheet; |
| 516 | const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation); | 516 | const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation); |
| 517 | sprite->frame = (sprite->frame + 1) % row->num_cols; | 517 | sprite->frame = (sprite->frame + 1) % row->num_cols; |
| 518 | } | 518 | } |
| 519 | 519 | ||
| 520 | iso->last_animation_time = t; | 520 | gfx->last_animation_time = t; |
| 521 | } | 521 | } |
| 522 | } | 522 | } |
| 523 | 523 | ||
| @@ -556,6 +556,7 @@ static void draw_rect( | |||
| 556 | Screen* screen, ivec2 top_left, int rect_width, int rect_height, | 556 | Screen* screen, ivec2 top_left, int rect_width, int rect_height, |
| 557 | const Pixel* pixels, const uint8_t* indices) { | 557 | const Pixel* pixels, const uint8_t* indices) { |
| 558 | assert(screen); | 558 | assert(screen); |
| 559 | assert(pixels); | ||
| 559 | 560 | ||
| 560 | #define rect_pixel(X, Y) \ | 561 | #define rect_pixel(X, Y) \ |
| 561 | (indices ? pixels[indices[Y * rect_width + X]] : pixels[Y * rect_width + X]) | 562 | (indices ? pixels[indices[Y * rect_width + X]] : pixels[Y * rect_width + X]) |
| @@ -584,116 +585,116 @@ static void draw_rect( | |||
| 584 | } | 585 | } |
| 585 | 586 | ||
| 586 | /// Draw a tile in an orthogonal map. | 587 | /// Draw a tile in an orthogonal map. |
| 587 | static void draw_tile_ortho(IsoGfx* iso, Tile tile, int x, int y) { | 588 | static void draw_tile_ortho(Gfx2d* gfx, Tile tile, int x, int y) { |
| 588 | assert(iso); | 589 | assert(gfx); |
| 589 | assert(iso->tileset); | 590 | assert(gfx->tileset); |
| 590 | assert(x >= 0); | 591 | assert(x >= 0); |
| 591 | assert(y >= 0); | 592 | assert(y >= 0); |
| 592 | assert(x < iso->map->world_width); | 593 | assert(x < gfx->map->world_width); |
| 593 | assert(y < iso->map->world_height); | 594 | assert(y < gfx->map->world_height); |
| 594 | 595 | ||
| 595 | const Ts_Tile* pTile = ts_tileset_get_tile(iso->tileset, tile); | 596 | const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile); |
| 596 | const Pixel* pixels = ts_tileset_get_tile_pixels(iso->tileset, tile); | 597 | const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile); |
| 597 | 598 | ||
| 598 | const ivec2 screen_origin = map2screen( | 599 | const ivec2 screen_origin = map2screen( |
| 599 | iso->camera, iso->map->base_tile_width, iso->map->base_tile_height, x, y); | 600 | gfx->camera, gfx->map->base_tile_width, gfx->map->base_tile_height, x, y); |
| 600 | 601 | ||
| 601 | draw_rect( | 602 | draw_rect( |
| 602 | &iso->screen, screen_origin, pTile->width, pTile->height, pixels, | 603 | &gfx->screen, screen_origin, pTile->width, pTile->height, pixels, |
| 603 | nullptr); | 604 | nullptr); |
| 604 | } | 605 | } |
| 605 | 606 | ||
| 606 | /// Draw a tile in an isometric map. | 607 | /// Draw a tile in an isometric map. |
| 607 | static void draw_tile_iso(IsoGfx* iso, Tile tile, int iso_x, int iso_y) { | 608 | static void draw_tile_iso(Gfx2d* gfx, Tile tile, int iso_x, int iso_y) { |
| 608 | assert(iso); | 609 | assert(gfx); |
| 609 | assert(iso->tileset); | 610 | assert(gfx->tileset); |
| 610 | assert(iso_x >= 0); | 611 | assert(iso_x >= 0); |
| 611 | assert(iso_y >= 0); | 612 | assert(iso_y >= 0); |
| 612 | assert(iso_x < iso->map->world_width); | 613 | assert(iso_x < gfx->map->world_width); |
| 613 | assert(iso_y < iso->map->world_height); | 614 | assert(iso_y < gfx->map->world_height); |
| 614 | 615 | ||
| 615 | const Ts_Tile* pTile = ts_tileset_get_tile(iso->tileset, tile); | 616 | const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile); |
| 616 | const Pixel* pixels = ts_tileset_get_tile_pixels(iso->tileset, tile); | 617 | const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile); |
| 617 | 618 | ||
| 618 | // Compute the screen coordinates of the top diamond-corner of the tile (the | 619 | // Compute the screen coordinates of the top diamond-corner of the tile (the |
| 619 | // base tile for super tiles). | 620 | // base tile for super tiles). |
| 620 | // World (0, 0) -> (screen_width / 2, 0). | 621 | // World (0, 0) -> (screen_width / 2, 0). |
| 621 | const ivec2 screen_origin = | 622 | const ivec2 screen_origin = |
| 622 | iso2cart(iso->iso_space, iso->camera, iso_x, iso_y); | 623 | iso2cart(gfx->iso_space, gfx->camera, iso_x, iso_y); |
| 623 | 624 | ||
| 624 | // Move from the top diamond-corner to the top-left corner of the tile image. | 625 | // Move from the top diamond-corner to the top-left corner of the tile image. |
| 625 | // For regular tiles, tile height == base tile height, so the y offset is 0. | 626 | // For regular tiles, tile height == base tile height, so the y offset is 0. |
| 626 | // For super tiles, move as high up as the height of the tile. | 627 | // For super tiles, move as high up as the height of the tile. |
| 627 | const ivec2 offset = { | 628 | const ivec2 offset = { |
| 628 | -(iso->map->base_tile_width / 2), | 629 | -(gfx->map->base_tile_width / 2), |
| 629 | pTile->height - iso->map->base_tile_height}; | 630 | pTile->height - gfx->map->base_tile_height}; |
| 630 | const ivec2 top_left = ivec2_add(screen_origin, offset); | 631 | const ivec2 top_left = ivec2_add(screen_origin, offset); |
| 631 | 632 | ||
| 632 | draw_rect( | 633 | draw_rect( |
| 633 | &iso->screen, top_left, pTile->width, pTile->height, pixels, nullptr); | 634 | &gfx->screen, top_left, pTile->width, pTile->height, pixels, nullptr); |
| 634 | } | 635 | } |
| 635 | 636 | ||
| 636 | static void draw_map_ortho(IsoGfx* iso) { | 637 | static void draw_map_ortho(Gfx2d* gfx) { |
| 637 | assert(iso); | 638 | assert(gfx); |
| 638 | assert(iso->map); | 639 | assert(gfx->map); |
| 639 | 640 | ||
| 640 | // TODO: Same TODOs as in draw_map_iso(). | 641 | // TODO: Same TODOs as in draw_map_iso(). |
| 641 | 642 | ||
| 642 | const Tm_Layer* layer = tm_map_get_layer(iso->map, 0); | 643 | const Tm_Layer* layer = tm_map_get_layer(gfx->map, 0); |
| 643 | 644 | ||
| 644 | for (int wy = 0; wy < iso->map->world_height; ++wy) { | 645 | for (int wy = 0; wy < gfx->map->world_height; ++wy) { |
| 645 | for (int wx = 0; wx < iso->map->world_width; ++wx) { | 646 | for (int wx = 0; wx < gfx->map->world_width; ++wx) { |
| 646 | const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy); | 647 | const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy); |
| 647 | draw_tile_ortho(iso, tile, wx, wy); | 648 | draw_tile_ortho(gfx, tile, wx, wy); |
| 648 | } | 649 | } |
| 649 | } | 650 | } |
| 650 | } | 651 | } |
| 651 | 652 | ||
| 652 | static void draw_map_iso(IsoGfx* iso) { | 653 | static void draw_map_iso(Gfx2d* gfx) { |
| 653 | assert(iso); | 654 | assert(gfx); |
| 654 | assert(iso->map); | 655 | assert(gfx->map); |
| 655 | 656 | ||
| 656 | // TODO: Support for multiple layers. | 657 | // TODO: Support for multiple layers. |
| 657 | const Tm_Layer* layer = tm_map_get_layer(iso->map, 0); | 658 | const Tm_Layer* layer = tm_map_get_layer(gfx->map, 0); |
| 658 | 659 | ||
| 659 | // TODO: Culling. | 660 | // TODO: Culling. |
| 660 | // Ex: map the screen corners to tile space to cull. | 661 | // Ex: map the screen corners to tile space to cull. |
| 661 | // Ex: walk in screen space and fetch the tile. | 662 | // Ex: walk in screen space and fetch the tile. |
| 662 | // The tile-centric approach might be more cache-friendly since the | 663 | // The tile-centric approach might be more cache-friendly since the |
| 663 | // screen-centric approach would juggle multiple tiles throughout the scan. | 664 | // screen-centric approach would juggle multiple tiles throughout the scan. |
| 664 | for (int wy = 0; wy < iso->map->world_height; ++wy) { | 665 | for (int wy = 0; wy < gfx->map->world_height; ++wy) { |
| 665 | for (int wx = 0; wx < iso->map->world_width; ++wx) { | 666 | for (int wx = 0; wx < gfx->map->world_width; ++wx) { |
| 666 | const Tile tile = tm_layer_get_tile(iso->map, layer, wx, wy); | 667 | const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy); |
| 667 | draw_tile_iso(iso, tile, wx, wy); | 668 | draw_tile_iso(gfx, tile, wx, wy); |
| 668 | } | 669 | } |
| 669 | } | 670 | } |
| 670 | } | 671 | } |
| 671 | 672 | ||
| 672 | static void draw_map(IsoGfx* iso) { | 673 | static void draw_map(Gfx2d* gfx) { |
| 673 | assert(iso); | 674 | assert(gfx); |
| 674 | assert(iso->map); | 675 | assert(gfx->map); |
| 675 | assert(iso->screen.pixels); | 676 | assert(gfx->screen.pixels); |
| 676 | 677 | ||
| 677 | const int W = iso->screen.width; | 678 | const int W = gfx->screen.width; |
| 678 | const int H = iso->screen.height; | 679 | const int H = gfx->screen.height; |
| 679 | 680 | ||
| 680 | memset(iso->screen.pixels, 0, W * H * sizeof(Pixel)); | 681 | memset(gfx->screen.pixels, 0, W * H * sizeof(Pixel)); |
| 681 | 682 | ||
| 682 | const Tm_Flags* flags = (const Tm_Flags*)&iso->map->flags; | 683 | const Tm_Flags* flags = (const Tm_Flags*)&gfx->map->flags; |
| 683 | switch (flags->orientation) { | 684 | switch (flags->orientation) { |
| 684 | case Tm_Orthogonal: | 685 | case Tm_Orthogonal: |
| 685 | draw_map_ortho(iso); | 686 | draw_map_ortho(gfx); |
| 686 | break; | 687 | break; |
| 687 | case Tm_Isometric: | 688 | case Tm_Isometric: |
| 688 | draw_map_iso(iso); | 689 | draw_map_iso(gfx); |
| 689 | break; | 690 | break; |
| 690 | } | 691 | } |
| 691 | } | 692 | } |
| 692 | 693 | ||
| 693 | /// Draw a sprite in an orthogonal/Cartesian coordinate system. | 694 | /// Draw a sprite in an orthogonal/Cartesian coordinate system. |
| 694 | static void draw_sprite_ortho( | 695 | static void draw_sprite_ortho( |
| 695 | IsoGfx* iso, const SpriteInstance* sprite, const Ss_SpriteSheet* sheet) { | 696 | Gfx2d* gfx, const SpriteInstance* sprite, const Ss_SpriteSheet* sheet) { |
| 696 | assert(iso); | 697 | assert(gfx); |
| 697 | assert(sprite); | 698 | assert(sprite); |
| 698 | assert(sheet); | 699 | assert(sheet); |
| 699 | assert(sprite->animation >= 0); | 700 | assert(sprite->animation >= 0); |
| @@ -704,20 +705,20 @@ static void draw_sprite_ortho( | |||
| 704 | // -base_tile_width/2 along the x-axis to align the sprite with the leftmost | 705 | // -base_tile_width/2 along the x-axis to align the sprite with the leftmost |
| 705 | // edge of the tile it is on. | 706 | // edge of the tile it is on. |
| 706 | const ivec2 screen_origin = map2screen( | 707 | const ivec2 screen_origin = map2screen( |
| 707 | iso->camera, iso->map->base_tile_width, iso->map->base_tile_height, | 708 | gfx->camera, gfx->map->base_tile_width, gfx->map->base_tile_height, |
| 708 | sprite->position.x, sprite->position.y); | 709 | sprite->position.x, sprite->position.y); |
| 709 | 710 | ||
| 710 | const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation); | 711 | const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation); |
| 711 | const uint8_t* frame = ss_get_sprite_sheet_sprite(sheet, row, sprite->frame); | 712 | const uint8_t* frame = ss_get_sprite_sheet_sprite(sheet, row, sprite->frame); |
| 712 | draw_rect( | 713 | draw_rect( |
| 713 | &iso->screen, screen_origin, sheet->sprite_width, sheet->sprite_height, | 714 | &gfx->screen, screen_origin, sheet->sprite_width, sheet->sprite_height, |
| 714 | sheet->palette.colours, frame); | 715 | sheet->palette.colours, frame); |
| 715 | } | 716 | } |
| 716 | 717 | ||
| 717 | /// Draw a sprite in an isometric coordinate system. | 718 | /// Draw a sprite in an isometric coordinate system. |
| 718 | static void draw_sprite_iso( | 719 | static void draw_sprite_iso( |
| 719 | IsoGfx* iso, const SpriteInstance* sprite, const Ss_SpriteSheet* sheet) { | 720 | Gfx2d* gfx, const SpriteInstance* sprite, const Ss_SpriteSheet* sheet) { |
| 720 | assert(iso); | 721 | assert(gfx); |
| 721 | assert(sprite); | 722 | assert(sprite); |
| 722 | assert(sheet); | 723 | assert(sheet); |
| 723 | assert(sprite->animation >= 0); | 724 | assert(sprite->animation >= 0); |
| @@ -728,92 +729,92 @@ static void draw_sprite_iso( | |||
| 728 | // -base_tile_width/2 along the x-axis to align the sprite with the leftmost | 729 | // -base_tile_width/2 along the x-axis to align the sprite with the leftmost |
| 729 | // edge of the tile it is on. | 730 | // edge of the tile it is on. |
| 730 | const ivec2 screen_origin = iso2cart( | 731 | const ivec2 screen_origin = iso2cart( |
| 731 | iso->iso_space, iso->camera, sprite->position.x, sprite->position.y); | 732 | gfx->iso_space, gfx->camera, sprite->position.x, sprite->position.y); |
| 732 | const ivec2 offset = {-(iso->map->base_tile_width / 2), 0}; | 733 | const ivec2 offset = {-(gfx->map->base_tile_width / 2), 0}; |
| 733 | const ivec2 top_left = ivec2_add(screen_origin, offset); | 734 | const ivec2 top_left = ivec2_add(screen_origin, offset); |
| 734 | 735 | ||
| 735 | const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation); | 736 | const Ss_Row* row = ss_get_sprite_sheet_row(sheet, sprite->animation); |
| 736 | const uint8_t* frame = ss_get_sprite_sheet_sprite(sheet, row, sprite->frame); | 737 | const uint8_t* frame = ss_get_sprite_sheet_sprite(sheet, row, sprite->frame); |
| 737 | draw_rect( | 738 | draw_rect( |
| 738 | &iso->screen, top_left, sheet->sprite_width, sheet->sprite_height, | 739 | &gfx->screen, top_left, sheet->sprite_width, sheet->sprite_height, |
| 739 | sheet->palette.colours, frame); | 740 | sheet->palette.colours, frame); |
| 740 | } | 741 | } |
| 741 | 742 | ||
| 742 | static void draw_sprites(IsoGfx* iso) { | 743 | static void draw_sprites(Gfx2d* gfx) { |
| 743 | assert(iso); | 744 | assert(gfx); |
| 744 | assert(iso->map); | 745 | assert(gfx->map); |
| 745 | 746 | ||
| 746 | const Tm_Flags* flags = (const Tm_Flags*)&iso->map->flags; | 747 | const Tm_Flags* flags = (const Tm_Flags*)&gfx->map->flags; |
| 747 | switch (flags->orientation) { | 748 | switch (flags->orientation) { |
| 748 | case Tm_Orthogonal: | 749 | case Tm_Orthogonal: |
| 749 | for (const SpriteInstance* sprite = iso->head_sprite; sprite; | 750 | for (const SpriteInstance* sprite = gfx->head_sprite; sprite; |
| 750 | sprite = sprite->next) { | 751 | sprite = sprite->next) { |
| 751 | draw_sprite_ortho(iso, sprite, sprite->sheet); | 752 | draw_sprite_ortho(gfx, sprite, sprite->sheet); |
| 752 | } | 753 | } |
| 753 | break; | 754 | break; |
| 754 | case Tm_Isometric: | 755 | case Tm_Isometric: |
| 755 | for (const SpriteInstance* sprite = iso->head_sprite; sprite; | 756 | for (const SpriteInstance* sprite = gfx->head_sprite; sprite; |
| 756 | sprite = sprite->next) { | 757 | sprite = sprite->next) { |
| 757 | draw_sprite_iso(iso, sprite, sprite->sheet); | 758 | draw_sprite_iso(gfx, sprite, sprite->sheet); |
| 758 | } | 759 | } |
| 759 | break; | 760 | break; |
| 760 | } | 761 | } |
| 761 | } | 762 | } |
| 762 | 763 | ||
| 763 | void isogfx_set_camera(IsoGfx* iso, int x, int y) { | 764 | void gfx2d_set_camera(Gfx2d* gfx, int x, int y) { |
| 764 | assert(iso); | 765 | assert(gfx); |
| 765 | iso->camera = (ivec2){x, y}; | 766 | gfx->camera = (ivec2){x, y}; |
| 766 | } | 767 | } |
| 767 | 768 | ||
| 768 | void isogfx_render(IsoGfx* iso) { | 769 | void gfx2d_render(Gfx2d* gfx) { |
| 769 | assert(iso); | 770 | assert(gfx); |
| 770 | draw_map(iso); | 771 | draw_map(gfx); |
| 771 | draw_sprites(iso); | 772 | draw_sprites(gfx); |
| 772 | } | 773 | } |
| 773 | 774 | ||
| 774 | void isogfx_draw_tile(IsoGfx* iso, int x, int y, Tile tile) { | 775 | void gfx2d_draw_tile(Gfx2d* gfx, int x, int y, Tile tile) { |
| 775 | assert(iso); | 776 | assert(gfx); |
| 776 | assert(iso->map); | 777 | assert(gfx->map); |
| 777 | 778 | ||
| 778 | const Tm_Flags* flags = (const Tm_Flags*)&iso->map->flags; | 779 | const Tm_Flags* flags = (const Tm_Flags*)&gfx->map->flags; |
| 779 | switch (flags->orientation) { | 780 | switch (flags->orientation) { |
| 780 | case Tm_Orthogonal: | 781 | case Tm_Orthogonal: |
| 781 | draw_tile_ortho(iso, tile, x, y); | 782 | draw_tile_ortho(gfx, tile, x, y); |
| 782 | break; | 783 | break; |
| 783 | case Tm_Isometric: | 784 | case Tm_Isometric: |
| 784 | draw_tile_iso(iso, tile, x, y); | 785 | draw_tile_iso(gfx, tile, x, y); |
| 785 | break; | 786 | break; |
| 786 | } | 787 | } |
| 787 | } | 788 | } |
| 788 | 789 | ||
| 789 | void isogfx_get_screen_size(const IsoGfx* iso, int* width, int* height) { | 790 | void gfx2d_get_screen_size(const Gfx2d* gfx, int* width, int* height) { |
| 790 | assert(iso); | 791 | assert(gfx); |
| 791 | assert(width); | 792 | assert(width); |
| 792 | assert(height); | 793 | assert(height); |
| 793 | *width = iso->screen.width; | 794 | *width = gfx->screen.width; |
| 794 | *height = iso->screen.height; | 795 | *height = gfx->screen.height; |
| 795 | } | 796 | } |
| 796 | 797 | ||
| 797 | const Pixel* isogfx_get_screen_buffer(const IsoGfx* iso) { | 798 | const Pixel* gfx2d_get_screen_buffer(const Gfx2d* gfx) { |
| 798 | assert(iso); | 799 | assert(gfx); |
| 799 | return iso->screen.pixels; | 800 | return gfx->screen.pixels; |
| 800 | } | 801 | } |
| 801 | 802 | ||
| 802 | void isogfx_pick_tile( | 803 | void gfx2d_pick_tile( |
| 803 | const IsoGfx* iso, double xcart, double ycart, int* xiso, int* yiso) { | 804 | const Gfx2d* gfx, double xcart, double ycart, int* xiso, int* yiso) { |
| 804 | assert(iso); | 805 | assert(gfx); |
| 805 | assert(xiso); | 806 | assert(xiso); |
| 806 | assert(yiso); | 807 | assert(yiso); |
| 807 | 808 | ||
| 808 | const vec2 camera = ivec2_to_vec2(iso->camera); | 809 | const vec2 camera = ivec2_to_vec2(gfx->camera); |
| 809 | const vec2 xy_cart = vec2_add(camera, (vec2){xcart, ycart}); | 810 | const vec2 xy_cart = vec2_add(camera, (vec2){xcart, ycart}); |
| 810 | 811 | ||
| 811 | const vec2 xy_iso = cart2iso( | 812 | const vec2 xy_iso = cart2iso( |
| 812 | xy_cart, iso->map->base_tile_width, iso->map->base_tile_height, | 813 | xy_cart, gfx->map->base_tile_width, gfx->map->base_tile_height, |
| 813 | iso->screen.width); | 814 | gfx->screen.width); |
| 814 | 815 | ||
| 815 | if ((0 <= xy_iso.x) && (xy_iso.x < iso->map->world_width) && | 816 | if ((0 <= xy_iso.x) && (xy_iso.x < gfx->map->world_width) && |
| 816 | (0 <= xy_iso.y) && (xy_iso.y < iso->map->world_height)) { | 817 | (0 <= xy_iso.y) && (xy_iso.y < gfx->map->world_height)) { |
| 817 | *xiso = (int)xy_iso.x; | 818 | *xiso = (int)xy_iso.x; |
| 818 | *yiso = (int)xy_iso.y; | 819 | *yiso = (int)xy_iso.y; |
| 819 | } else { | 820 | } else { |
