diff options
| author | 3gg <3gg@shellblade.net> | 2025-07-19 09:29:12 -0700 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-07-19 09:29:12 -0700 |
| commit | d1370b955f9a86c82f92d7368237ed96318de330 (patch) | |
| tree | fe59a07927e560da5dfe88c89c547ec3c3a47307 /include | |
| parent | 10cd24c9e5da615064c782effafc7477bf074054 (diff) | |
Allocate data from a stack allocator
Diffstat (limited to 'include')
| -rw-r--r-- | include/isogfx/asset.h | 149 | ||||
| -rw-r--r-- | include/isogfx/isogfx.h | 57 | ||||
| -rw-r--r-- | include/isogfx/types.h | 14 |
3 files changed, 161 insertions, 59 deletions
diff --git a/include/isogfx/asset.h b/include/isogfx/asset.h index 298c469..9aeb55d 100644 --- a/include/isogfx/asset.h +++ b/include/isogfx/asset.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | */ | 7 | */ |
| 8 | #pragma once | 8 | #pragma once |
| 9 | 9 | ||
| 10 | #include <isogfx/types.h> | ||
| 11 | |||
| 10 | #include <assert.h> | 12 | #include <assert.h> |
| 11 | #include <stdint.h> | 13 | #include <stdint.h> |
| 12 | 14 | ||
| @@ -18,16 +20,16 @@ | |||
| 18 | // ----------------------------------------------------------------------------- | 20 | // ----------------------------------------------------------------------------- |
| 19 | 21 | ||
| 20 | typedef struct Ts_Tile { | 22 | typedef struct Ts_Tile { |
| 21 | uint16_t width; // Tile width in pixels. | 23 | uint16_t width; // Tile width in pixels. |
| 22 | uint16_t height; // Tile height in pixels. | 24 | uint16_t height; // Tile height in pixels. |
| 23 | Pixel pixels[1]; // Count: width * height. | 25 | uint32_t pixels; // Byte offset into the Ts_TileSet's 'pixels'. |
| 24 | } Ts_Tile; | 26 | } Ts_Tile; |
| 25 | 27 | ||
| 26 | typedef struct Ts_TileSet { | 28 | typedef struct Ts_TileSet { |
| 27 | uint16_t num_tiles; | 29 | uint16_t num_tiles; |
| 28 | uint16_t max_tile_width; // Maximum tile width in pixels. | 30 | uint16_t _pad; |
| 29 | uint16_t max_tile_height; // Maximum tile height in pixels. | 31 | Ts_Tile tiles[1]; // Count: num_tiles. |
| 30 | Ts_Tile tiles[1]; // Count: num_tiles. | 32 | Pixel pixels[]; // Count: sum_i(tile[i].width * tile[i].height). |
| 31 | } Ts_TileSet; | 33 | } Ts_TileSet; |
| 32 | 34 | ||
| 33 | // ----------------------------------------------------------------------------- | 35 | // ----------------------------------------------------------------------------- |
| @@ -35,19 +37,17 @@ typedef struct Ts_TileSet { | |||
| 35 | // ----------------------------------------------------------------------------- | 37 | // ----------------------------------------------------------------------------- |
| 36 | 38 | ||
| 37 | typedef struct Tm_Layer { | 39 | typedef struct Tm_Layer { |
| 38 | union { | ||
| 39 | char tileset_path[ISOGFX_MAX_PATH_LENGTH]; // Relative to the Tm_Map file. | ||
| 40 | }; | ||
| 41 | Tile tiles[1]; // Count: world_width * world_height. | 40 | Tile tiles[1]; // Count: world_width * world_height. |
| 42 | } Tm_Layer; | 41 | } Tm_Layer; |
| 43 | 42 | ||
| 44 | typedef struct Tm_Map { | 43 | typedef struct Tm_Map { |
| 44 | char tileset_path[ISOGFX_MAX_PATH_LENGTH]; // Relative to the Tm_Map file. | ||
| 45 | uint16_t world_width; // World width in number of tiles. | 45 | uint16_t world_width; // World width in number of tiles. |
| 46 | uint16_t world_height; // World height in number of tiles. | 46 | uint16_t world_height; // World height in number of tiles. |
| 47 | uint16_t base_tile_width; | 47 | uint16_t base_tile_width; |
| 48 | uint16_t base_tile_height; | 48 | uint16_t base_tile_height; |
| 49 | uint16_t num_layers; | 49 | uint16_t num_layers; |
| 50 | Tm_Layer layers[1]; // Count: num_layers. | 50 | Tm_Layer layers[]; // Count: num_layers. |
| 51 | } Tm_Map; | 51 | } Tm_Map; |
| 52 | 52 | ||
| 53 | // ----------------------------------------------------------------------------- | 53 | // ----------------------------------------------------------------------------- |
| @@ -88,28 +88,117 @@ typedef struct Ss_SpriteSheet { | |||
| 88 | // Data accessors. | 88 | // Data accessors. |
| 89 | // ----------------------------------------------------------------------------- | 89 | // ----------------------------------------------------------------------------- |
| 90 | 90 | ||
| 91 | /// Return the next tile in the tile set. | 91 | /// Return the tile set's pixels. |
| 92 | static inline const Ts_Tile* ts_tileset_get_next_tile( | 92 | static inline const Pixel* ts_tileset_get_pixels(const Ts_TileSet* tileset) { |
| 93 | const Ts_TileSet* tileset, const Ts_Tile* tile) { | 93 | assert(tileset); |
| 94 | return (const Pixel*)((const uint8_t*)&tileset->tiles[0] + | ||
| 95 | (tileset->num_tiles * sizeof(Ts_Tile))); | ||
| 96 | } | ||
| 97 | |||
| 98 | /// Return the ith tile in the tile set. | ||
| 99 | static inline const Ts_Tile* ts_tileset_get_tile( | ||
| 100 | const Ts_TileSet* tileset, const int tile) { | ||
| 101 | assert(tileset); | ||
| 102 | assert(tile >= 0); | ||
| 103 | assert(tile < tileset->num_tiles); | ||
| 104 | return &tileset->tiles[tile]; | ||
| 105 | } | ||
| 106 | |||
| 107 | /// Return the ith tile in the tile set. | ||
| 108 | static inline Ts_Tile* ts_tileset_get_tile_mut( | ||
| 109 | Ts_TileSet* tileset, const int tile) { | ||
| 110 | return (Ts_Tile*)ts_tileset_get_tile(tileset, tile); | ||
| 111 | } | ||
| 112 | |||
| 113 | /// Return the ith tile's pixels. | ||
| 114 | static inline const Pixel* ts_tileset_get_tile_pixels( | ||
| 115 | const Ts_TileSet* tileset, const int tile) { | ||
| 94 | assert(tileset); | 116 | assert(tileset); |
| 117 | assert(tile >= 0); | ||
| 118 | assert(tile < tileset->num_tiles); | ||
| 119 | const Pixel* pixels = ts_tileset_get_pixels(tileset); | ||
| 120 | const Ts_Tile* pTile = ts_tileset_get_tile(tileset, tile); | ||
| 121 | return (const Pixel*)((const uint8_t*)pixels + pTile->pixels); | ||
| 122 | } | ||
| 123 | |||
| 124 | /// Return the ith tile's pixels. | ||
| 125 | static inline Pixel* ts_tileset_get_tile_pixels_mut( | ||
| 126 | Ts_TileSet* tileset, const int tile) { | ||
| 127 | return (Pixel*)ts_tileset_get_tile_pixels(tileset, tile); | ||
| 128 | } | ||
| 129 | |||
| 130 | /// Return the ith tile's pixels. | ||
| 131 | static inline const Pixel* ts_tile_get_pixels( | ||
| 132 | const Pixel* pixels, const Ts_Tile* tile) { | ||
| 133 | assert(pixels); | ||
| 95 | assert(tile); | 134 | assert(tile); |
| 96 | return (const Ts_Tile*)((const uint8_t*)tile + sizeof(Ts_Tile) + | 135 | return (const Pixel*)((const uint8_t*)pixels + tile->pixels); |
| 97 | ((tile->width * tile->height - 1) * sizeof(Pixel))); | 136 | } |
| 137 | |||
| 138 | /// Return the tile's pixel at (x,y). | ||
| 139 | static const Pixel* ts_tile_xy( | ||
| 140 | const Pixel* tile_pixels, const Ts_Tile* tile, int x, int y) { | ||
| 141 | assert(tile_pixels); | ||
| 142 | assert(tile); | ||
| 143 | assert(x >= 0); | ||
| 144 | assert(y >= 0); | ||
| 145 | assert(x < tile->width); | ||
| 146 | assert(y < tile->height); | ||
| 147 | return &tile_pixels[y * tile->width + x]; | ||
| 148 | } | ||
| 149 | |||
| 150 | /// Return the tile's pixel at (x,y). | ||
| 151 | static Pixel* ts_tile_xy_mut( | ||
| 152 | const Pixel* pixels, const Ts_Tile* tile, int x, int y) { | ||
| 153 | return (Pixel*)ts_tile_xy(pixels, tile, x, y); | ||
| 98 | } | 154 | } |
| 99 | 155 | ||
| 100 | /// Return the next layer in the tile map. | 156 | /// Return the ith layer in the tile map. |
| 101 | static inline const Tm_Layer* tm_map_get_next_layer( | 157 | static inline const Tm_Layer* tm_map_get_layer( |
| 102 | const Tm_Map* map, const Tm_Layer* layer) { | 158 | const Tm_Map* map, const int layer) { |
| 103 | assert(map); | 159 | assert(map); |
| 104 | assert(layer); | 160 | assert(layer >= 0); |
| 105 | return (const Tm_Layer*)((const uint8_t*)layer + sizeof(Tm_Layer) + | 161 | assert(layer < map->num_layers); |
| 106 | ((map->world_width * map->world_height - 1) * | 162 | return (const Tm_Layer*)((const uint8_t*)map->layers + |
| 163 | (layer * map->world_width * map->world_height * | ||
| 107 | sizeof(Tile))); | 164 | sizeof(Tile))); |
| 108 | } | 165 | } |
| 109 | 166 | ||
| 167 | /// Return the ith layer in the tile map. | ||
| 168 | static inline Tm_Layer* tm_map_get_layer_mut(Tm_Map* map, const int layer) { | ||
| 169 | assert(map); | ||
| 170 | assert(layer >= 0); | ||
| 171 | assert(layer < map->num_layers); | ||
| 172 | return (Tm_Layer*)tm_map_get_layer(map, layer); | ||
| 173 | } | ||
| 174 | |||
| 175 | /// Return the tile in the layer. | ||
| 176 | static inline const Tile* tm_layer_get_tile_const_ref( | ||
| 177 | const Tm_Map* map, const Tm_Layer* layer, const int x, const int y) { | ||
| 178 | assert(map); | ||
| 179 | assert(layer); | ||
| 180 | assert(x >= 0); | ||
| 181 | assert(y >= 0); | ||
| 182 | assert(x < map->world_width); | ||
| 183 | assert(y < map->world_height); | ||
| 184 | return &layer->tiles[y * map->world_width + x]; | ||
| 185 | } | ||
| 186 | |||
| 187 | /// Return the tile in the layer. | ||
| 188 | static inline Tile tm_layer_get_tile( | ||
| 189 | const Tm_Map* map, const Tm_Layer* layer, const int x, const int y) { | ||
| 190 | return *tm_layer_get_tile_const_ref(map, layer, x, y); | ||
| 191 | } | ||
| 192 | |||
| 193 | /// Return the tile in the layer. | ||
| 194 | static inline Tile* tm_layer_get_tile_mut( | ||
| 195 | Tm_Map* map, Tm_Layer* layer, const int x, const int y) { | ||
| 196 | return (Tile*)tm_layer_get_tile_const_ref(map, layer, x, y); | ||
| 197 | } | ||
| 198 | |||
| 110 | /// Return the ith row in the sprite sheet. | 199 | /// Return the ith row in the sprite sheet. |
| 111 | static inline const Ss_Row* get_sprite_sheet_row( | 200 | static inline const Ss_Row* ss_get_sprite_sheet_row( |
| 112 | const Ss_SpriteSheet* sheet, int row) { | 201 | const Ss_SpriteSheet* sheet, const int row) { |
| 113 | assert(sheet); | 202 | assert(sheet); |
| 114 | assert(row >= 0); | 203 | assert(row >= 0); |
| 115 | assert(row < sheet->num_rows); | 204 | assert(row < sheet->num_rows); |
| @@ -120,8 +209,8 @@ static inline const Ss_Row* get_sprite_sheet_row( | |||
| 120 | } | 209 | } |
| 121 | 210 | ||
| 122 | /// Return the ith sprite in the row. | 211 | /// Return the ith sprite in the row. |
| 123 | static inline const uint8_t* get_sprite_sheet_sprite( | 212 | static inline const uint8_t* ss_get_sprite_sheet_sprite( |
| 124 | const Ss_SpriteSheet* sheet, const Ss_Row* row, int col) { | 213 | const Ss_SpriteSheet* sheet, const Ss_Row* row, const int col) { |
| 125 | assert(sheet); | 214 | assert(sheet); |
| 126 | assert(row); | 215 | assert(row); |
| 127 | assert(col >= 0); | 216 | assert(col >= 0); |
| @@ -130,3 +219,13 @@ static inline const uint8_t* get_sprite_sheet_sprite( | |||
| 130 | const uint8_t* sprite = &row->pixels[sprite_offset]; | 219 | const uint8_t* sprite = &row->pixels[sprite_offset]; |
| 131 | return sprite; | 220 | return sprite; |
| 132 | } | 221 | } |
| 222 | |||
| 223 | // ----------------------------------------------------------------------------- | ||
| 224 | // Validation. | ||
| 225 | // ----------------------------------------------------------------------------- | ||
| 226 | |||
| 227 | /// Validate the tile set. | ||
| 228 | bool ts_validate_tileset(const Ts_TileSet* tileset); | ||
| 229 | |||
| 230 | /// Validate the map. | ||
| 231 | bool tm_validate_map(const Tm_Map* map, const Ts_TileSet* tileset); | ||
diff --git a/include/isogfx/isogfx.h b/include/isogfx/isogfx.h index 3421a7b..93c6d4e 100644 --- a/include/isogfx/isogfx.h +++ b/include/isogfx/isogfx.h | |||
| @@ -3,26 +3,18 @@ | |||
| 3 | */ | 3 | */ |
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <stdbool.h> | 6 | #include <isogfx/types.h> |
| 7 | |||
| 8 | #include <stddef.h> | ||
| 7 | #include <stdint.h> | 9 | #include <stdint.h> |
| 8 | 10 | ||
| 9 | typedef struct IsoGfx IsoGfx; | 11 | typedef struct IsoGfx IsoGfx; |
| 10 | 12 | ||
| 11 | /// Sprite sheet handle. | 13 | /// Sprite sheet handle. |
| 12 | typedef uint16_t SpriteSheet; | 14 | typedef uintptr_t SpriteSheet; |
| 13 | 15 | ||
| 14 | /// Sprite handle. | 16 | /// Sprite handle. |
| 15 | typedef uint16_t Sprite; | 17 | typedef uintptr_t Sprite; |
| 16 | |||
| 17 | /// Tile handle. | ||
| 18 | typedef uint16_t Tile; | ||
| 19 | |||
| 20 | /// Colour channel. | ||
| 21 | typedef uint8_t Channel; | ||
| 22 | |||
| 23 | typedef struct Pixel { | ||
| 24 | Channel r, g, b, a; | ||
| 25 | } Pixel; | ||
| 26 | 18 | ||
| 27 | typedef enum TileDescType { | 19 | typedef enum TileDescType { |
| 28 | TileFromColour, | 20 | TileFromColour, |
| @@ -32,32 +24,32 @@ typedef enum TileDescType { | |||
| 32 | 24 | ||
| 33 | typedef struct TileDesc { | 25 | typedef struct TileDesc { |
| 34 | TileDescType type; | 26 | TileDescType type; |
| 35 | int width; /// Tile width in pixels. | 27 | int width; // Tile width in pixels. |
| 36 | int height; /// Tile height in pixels. | 28 | int height; // Tile height in pixels. |
| 37 | union { | 29 | union { |
| 38 | Pixel colour; /// Constant colour tile. | 30 | Pixel colour; // Constant colour tile. |
| 39 | struct { | 31 | struct { |
| 40 | const char* path; | 32 | const char* path; |
| 41 | } file; | 33 | } file; |
| 42 | struct { | 34 | struct { |
| 43 | const uint8_t* data; /// sizeof(Pixel) * width * height | 35 | const uint8_t* data; // sizeof(Pixel) * width * height |
| 44 | } mem; | 36 | } mem; |
| 45 | }; | 37 | }; |
| 46 | } TileDesc; | 38 | } TileDesc; |
| 47 | 39 | ||
| 48 | typedef struct WorldDesc { | 40 | typedef struct WorldDesc { |
| 49 | int tile_width; /// Base tile width in pixels. | 41 | int tile_width; // Base tile width in pixels. |
| 50 | int tile_height; /// Base tile height in pixels. | 42 | int tile_height; // Base tile height in pixels. |
| 51 | int world_width; /// World width in tiles. | 43 | int world_width; // World width in tiles. |
| 52 | int world_height; /// World height in tiles. | 44 | int world_height; // World height in tiles. |
| 53 | int max_num_tiles; /// 0 for an implementation-defined default. | 45 | int num_tiles; // Number of tiles to allocate memory for. |
| 54 | } WorldDesc; | 46 | } WorldDesc; |
| 55 | 47 | ||
| 56 | typedef struct IsoGfxDesc { | 48 | typedef struct IsoGfxDesc { |
| 57 | int screen_width; /// Screen width in pixels. | 49 | void* memory; // Block of memory for the engine to use. |
| 58 | int screen_height; /// Screen height in pixels. | 50 | size_t memory_size; // Size of memory block in bytes. |
| 59 | int max_num_sprites; /// 0 for an implementation-defined default. | 51 | int screen_width; // Screen width in pixels. |
| 60 | int sprite_sheet_pool_size_bytes; /// 0 for an implementation-defined default. | 52 | int screen_height; // Screen height in pixels. |
| 61 | } IsoGfxDesc; | 53 | } IsoGfxDesc; |
| 62 | 54 | ||
| 63 | /// Create a new isometric graphics engine. | 55 | /// Create a new isometric graphics engine. |
| @@ -66,8 +58,11 @@ IsoGfx* isogfx_new(const IsoGfxDesc*); | |||
| 66 | /// Destroy the isometric graphics engine. | 58 | /// Destroy the isometric graphics engine. |
| 67 | void isogfx_del(IsoGfx**); | 59 | void isogfx_del(IsoGfx**); |
| 68 | 60 | ||
| 61 | /// Clear all loaded worlds and sprites. | ||
| 62 | void isogfx_clear(IsoGfx*); | ||
| 63 | |||
| 69 | /// Create an empty world. | 64 | /// Create an empty world. |
| 70 | bool isogfx_make_world(IsoGfx*, const WorldDesc*); | 65 | void isogfx_make_world(IsoGfx*, const WorldDesc*); |
| 71 | 66 | ||
| 72 | /// Load a world from a tile map (.TM) file. | 67 | /// Load a world from a tile map (.TM) file. |
| 73 | bool isogfx_load_world(IsoGfx*, const char* filepath); | 68 | bool isogfx_load_world(IsoGfx*, const char* filepath); |
| @@ -88,14 +83,11 @@ void isogfx_set_tile(IsoGfx*, int x, int y, Tile); | |||
| 88 | void isogfx_set_tiles(IsoGfx*, int x0, int y0, int x1, int y1, Tile); | 83 | void isogfx_set_tiles(IsoGfx*, int x0, int y0, int x1, int y1, Tile); |
| 89 | 84 | ||
| 90 | /// Load a sprite sheet (.SS) file. | 85 | /// Load a sprite sheet (.SS) file. |
| 91 | bool isogfx_load_sprite_sheet(IsoGfx*, const char* filepath, SpriteSheet*); | 86 | SpriteSheet isogfx_load_sprite_sheet(IsoGfx*, const char* filepath); |
| 92 | 87 | ||
| 93 | /// Create an animated sprite. | 88 | /// Create an animated sprite. |
| 94 | Sprite isogfx_make_sprite(IsoGfx*, SpriteSheet); | 89 | Sprite isogfx_make_sprite(IsoGfx*, SpriteSheet); |
| 95 | 90 | ||
| 96 | /// Destroy the sprite. | ||
| 97 | void isogfx_del_sprite(IsoGfx*, Sprite); | ||
| 98 | |||
| 99 | /// Destroy all the sprites. | 91 | /// Destroy all the sprites. |
| 100 | void isogfx_del_sprites(IsoGfx*); | 92 | void isogfx_del_sprites(IsoGfx*); |
| 101 | 93 | ||
| @@ -120,9 +112,6 @@ void isogfx_render(IsoGfx*); | |||
| 120 | /// position (x,y) instead, use isogfx_set_tile(). | 112 | /// position (x,y) instead, use isogfx_set_tile(). |
| 121 | void isogfx_draw_tile(IsoGfx*, int x, int y, Tile); | 113 | void isogfx_draw_tile(IsoGfx*, int x, int y, Tile); |
| 122 | 114 | ||
| 123 | /// Resize the virtual screen's dimensions. | ||
| 124 | bool isogfx_resize(IsoGfx*, int screen_width, int screen_height); | ||
| 125 | |||
| 126 | /// Get the virtual screen's dimensions. | 115 | /// Get the virtual screen's dimensions. |
| 127 | void isogfx_get_screen_size(const IsoGfx*, int* width, int* height); | 116 | void isogfx_get_screen_size(const IsoGfx*, int* width, int* height); |
| 128 | 117 | ||
diff --git a/include/isogfx/types.h b/include/isogfx/types.h new file mode 100644 index 0000000..ce275dc --- /dev/null +++ b/include/isogfx/types.h | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <stdint.h> | ||
| 4 | |||
| 5 | /// Colour channel. | ||
| 6 | typedef uint8_t Channel; | ||
| 7 | |||
| 8 | /// Pixel. | ||
| 9 | typedef struct Pixel { | ||
| 10 | Channel r, g, b, a; | ||
| 11 | } Pixel; | ||
| 12 | |||
| 13 | /// Tile handle/index. | ||
| 14 | typedef uint16_t Tile; | ||
