From d1370b955f9a86c82f92d7368237ed96318de330 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 19 Jul 2025 09:29:12 -0700 Subject: Allocate data from a stack allocator --- include/isogfx/asset.h | 149 ++++++++++++++++++++++++++++++++++++++++-------- include/isogfx/isogfx.h | 57 ++++++++---------- include/isogfx/types.h | 14 +++++ 3 files changed, 161 insertions(+), 59 deletions(-) create mode 100644 include/isogfx/types.h (limited to 'include') 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 @@ */ #pragma once +#include + #include #include @@ -18,16 +20,16 @@ // ----------------------------------------------------------------------------- typedef struct Ts_Tile { - uint16_t width; // Tile width in pixels. - uint16_t height; // Tile height in pixels. - Pixel pixels[1]; // Count: width * height. + uint16_t width; // Tile width in pixels. + uint16_t height; // Tile height in pixels. + uint32_t pixels; // Byte offset into the Ts_TileSet's 'pixels'. } Ts_Tile; typedef struct Ts_TileSet { uint16_t num_tiles; - uint16_t max_tile_width; // Maximum tile width in pixels. - uint16_t max_tile_height; // Maximum tile height in pixels. - Ts_Tile tiles[1]; // Count: num_tiles. + uint16_t _pad; + Ts_Tile tiles[1]; // Count: num_tiles. + Pixel pixels[]; // Count: sum_i(tile[i].width * tile[i].height). } Ts_TileSet; // ----------------------------------------------------------------------------- @@ -35,19 +37,17 @@ typedef struct Ts_TileSet { // ----------------------------------------------------------------------------- typedef struct Tm_Layer { - union { - char tileset_path[ISOGFX_MAX_PATH_LENGTH]; // Relative to the Tm_Map file. - }; Tile tiles[1]; // Count: world_width * world_height. } Tm_Layer; typedef struct Tm_Map { + char tileset_path[ISOGFX_MAX_PATH_LENGTH]; // Relative to the Tm_Map file. uint16_t world_width; // World width in number of tiles. uint16_t world_height; // World height in number of tiles. uint16_t base_tile_width; uint16_t base_tile_height; uint16_t num_layers; - Tm_Layer layers[1]; // Count: num_layers. + Tm_Layer layers[]; // Count: num_layers. } Tm_Map; // ----------------------------------------------------------------------------- @@ -88,28 +88,117 @@ typedef struct Ss_SpriteSheet { // Data accessors. // ----------------------------------------------------------------------------- -/// Return the next tile in the tile set. -static inline const Ts_Tile* ts_tileset_get_next_tile( - const Ts_TileSet* tileset, const Ts_Tile* tile) { +/// Return the tile set's pixels. +static inline const Pixel* ts_tileset_get_pixels(const Ts_TileSet* tileset) { + assert(tileset); + return (const Pixel*)((const uint8_t*)&tileset->tiles[0] + + (tileset->num_tiles * sizeof(Ts_Tile))); +} + +/// Return the ith tile in the tile set. +static inline const Ts_Tile* ts_tileset_get_tile( + const Ts_TileSet* tileset, const int tile) { + assert(tileset); + assert(tile >= 0); + assert(tile < tileset->num_tiles); + return &tileset->tiles[tile]; +} + +/// Return the ith tile in the tile set. +static inline Ts_Tile* ts_tileset_get_tile_mut( + Ts_TileSet* tileset, const int tile) { + return (Ts_Tile*)ts_tileset_get_tile(tileset, tile); +} + +/// Return the ith tile's pixels. +static inline const Pixel* ts_tileset_get_tile_pixels( + const Ts_TileSet* tileset, const int tile) { assert(tileset); + assert(tile >= 0); + assert(tile < tileset->num_tiles); + const Pixel* pixels = ts_tileset_get_pixels(tileset); + const Ts_Tile* pTile = ts_tileset_get_tile(tileset, tile); + return (const Pixel*)((const uint8_t*)pixels + pTile->pixels); +} + +/// Return the ith tile's pixels. +static inline Pixel* ts_tileset_get_tile_pixels_mut( + Ts_TileSet* tileset, const int tile) { + return (Pixel*)ts_tileset_get_tile_pixels(tileset, tile); +} + +/// Return the ith tile's pixels. +static inline const Pixel* ts_tile_get_pixels( + const Pixel* pixels, const Ts_Tile* tile) { + assert(pixels); assert(tile); - return (const Ts_Tile*)((const uint8_t*)tile + sizeof(Ts_Tile) + - ((tile->width * tile->height - 1) * sizeof(Pixel))); + return (const Pixel*)((const uint8_t*)pixels + tile->pixels); +} + +/// Return the tile's pixel at (x,y). +static const Pixel* ts_tile_xy( + const Pixel* tile_pixels, const Ts_Tile* tile, int x, int y) { + assert(tile_pixels); + assert(tile); + assert(x >= 0); + assert(y >= 0); + assert(x < tile->width); + assert(y < tile->height); + return &tile_pixels[y * tile->width + x]; +} + +/// Return the tile's pixel at (x,y). +static Pixel* ts_tile_xy_mut( + const Pixel* pixels, const Ts_Tile* tile, int x, int y) { + return (Pixel*)ts_tile_xy(pixels, tile, x, y); } -/// Return the next layer in the tile map. -static inline const Tm_Layer* tm_map_get_next_layer( - const Tm_Map* map, const Tm_Layer* layer) { +/// Return the ith layer in the tile map. +static inline const Tm_Layer* tm_map_get_layer( + const Tm_Map* map, const int layer) { assert(map); - assert(layer); - return (const Tm_Layer*)((const uint8_t*)layer + sizeof(Tm_Layer) + - ((map->world_width * map->world_height - 1) * + assert(layer >= 0); + assert(layer < map->num_layers); + return (const Tm_Layer*)((const uint8_t*)map->layers + + (layer * map->world_width * map->world_height * sizeof(Tile))); } +/// Return the ith layer in the tile map. +static inline Tm_Layer* tm_map_get_layer_mut(Tm_Map* map, const int layer) { + assert(map); + assert(layer >= 0); + assert(layer < map->num_layers); + return (Tm_Layer*)tm_map_get_layer(map, layer); +} + +/// Return the tile in the layer. +static inline const Tile* tm_layer_get_tile_const_ref( + const Tm_Map* map, const Tm_Layer* layer, const int x, const int y) { + assert(map); + assert(layer); + assert(x >= 0); + assert(y >= 0); + assert(x < map->world_width); + assert(y < map->world_height); + return &layer->tiles[y * map->world_width + x]; +} + +/// Return the tile in the layer. +static inline Tile tm_layer_get_tile( + const Tm_Map* map, const Tm_Layer* layer, const int x, const int y) { + return *tm_layer_get_tile_const_ref(map, layer, x, y); +} + +/// Return the tile in the layer. +static inline Tile* tm_layer_get_tile_mut( + Tm_Map* map, Tm_Layer* layer, const int x, const int y) { + return (Tile*)tm_layer_get_tile_const_ref(map, layer, x, y); +} + /// Return the ith row in the sprite sheet. -static inline const Ss_Row* get_sprite_sheet_row( - const Ss_SpriteSheet* sheet, int row) { +static inline const Ss_Row* ss_get_sprite_sheet_row( + const Ss_SpriteSheet* sheet, const int row) { assert(sheet); assert(row >= 0); assert(row < sheet->num_rows); @@ -120,8 +209,8 @@ static inline const Ss_Row* get_sprite_sheet_row( } /// Return the ith sprite in the row. -static inline const uint8_t* get_sprite_sheet_sprite( - const Ss_SpriteSheet* sheet, const Ss_Row* row, int col) { +static inline const uint8_t* ss_get_sprite_sheet_sprite( + const Ss_SpriteSheet* sheet, const Ss_Row* row, const int col) { assert(sheet); assert(row); assert(col >= 0); @@ -130,3 +219,13 @@ static inline const uint8_t* get_sprite_sheet_sprite( const uint8_t* sprite = &row->pixels[sprite_offset]; return sprite; } + +// ----------------------------------------------------------------------------- +// Validation. +// ----------------------------------------------------------------------------- + +/// Validate the tile set. +bool ts_validate_tileset(const Ts_TileSet* tileset); + +/// Validate the map. +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 @@ */ #pragma once -#include +#include + +#include #include typedef struct IsoGfx IsoGfx; /// Sprite sheet handle. -typedef uint16_t SpriteSheet; +typedef uintptr_t SpriteSheet; /// Sprite handle. -typedef uint16_t Sprite; - -/// Tile handle. -typedef uint16_t Tile; - -/// Colour channel. -typedef uint8_t Channel; - -typedef struct Pixel { - Channel r, g, b, a; -} Pixel; +typedef uintptr_t Sprite; typedef enum TileDescType { TileFromColour, @@ -32,32 +24,32 @@ typedef enum TileDescType { typedef struct TileDesc { TileDescType type; - int width; /// Tile width in pixels. - int height; /// Tile height in pixels. + int width; // Tile width in pixels. + int height; // Tile height in pixels. union { - Pixel colour; /// Constant colour tile. + Pixel colour; // Constant colour tile. struct { const char* path; } file; struct { - const uint8_t* data; /// sizeof(Pixel) * width * height + const uint8_t* data; // sizeof(Pixel) * width * height } mem; }; } TileDesc; typedef struct WorldDesc { - int tile_width; /// Base tile width in pixels. - int tile_height; /// Base tile height in pixels. - int world_width; /// World width in tiles. - int world_height; /// World height in tiles. - int max_num_tiles; /// 0 for an implementation-defined default. + int tile_width; // Base tile width in pixels. + int tile_height; // Base tile height in pixels. + int world_width; // World width in tiles. + int world_height; // World height in tiles. + int num_tiles; // Number of tiles to allocate memory for. } WorldDesc; typedef struct IsoGfxDesc { - int screen_width; /// Screen width in pixels. - int screen_height; /// Screen height in pixels. - int max_num_sprites; /// 0 for an implementation-defined default. - int sprite_sheet_pool_size_bytes; /// 0 for an implementation-defined default. + void* memory; // Block of memory for the engine to use. + 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; /// Create a new isometric graphics engine. @@ -66,8 +58,11 @@ IsoGfx* isogfx_new(const IsoGfxDesc*); /// Destroy the isometric graphics engine. void isogfx_del(IsoGfx**); +/// Clear all loaded worlds and sprites. +void isogfx_clear(IsoGfx*); + /// Create an empty world. -bool isogfx_make_world(IsoGfx*, const WorldDesc*); +void isogfx_make_world(IsoGfx*, const WorldDesc*); /// Load a world from a tile map (.TM) file. bool isogfx_load_world(IsoGfx*, const char* filepath); @@ -88,14 +83,11 @@ void isogfx_set_tile(IsoGfx*, int x, int y, Tile); void isogfx_set_tiles(IsoGfx*, int x0, int y0, int x1, int y1, Tile); /// Load a sprite sheet (.SS) file. -bool isogfx_load_sprite_sheet(IsoGfx*, const char* filepath, SpriteSheet*); +SpriteSheet isogfx_load_sprite_sheet(IsoGfx*, const char* filepath); /// Create an animated sprite. Sprite isogfx_make_sprite(IsoGfx*, SpriteSheet); -/// Destroy the sprite. -void isogfx_del_sprite(IsoGfx*, Sprite); - /// Destroy all the sprites. void isogfx_del_sprites(IsoGfx*); @@ -120,9 +112,6 @@ void isogfx_render(IsoGfx*); /// position (x,y) instead, use isogfx_set_tile(). void isogfx_draw_tile(IsoGfx*, int x, int y, Tile); -/// Resize the virtual screen's dimensions. -bool isogfx_resize(IsoGfx*, int screen_width, int screen_height); - /// Get the virtual screen's dimensions. void isogfx_get_screen_size(const IsoGfx*, int* width, int* height); 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 @@ +#pragma once + +#include + +/// Colour channel. +typedef uint8_t Channel; + +/// Pixel. +typedef struct Pixel { + Channel r, g, b, a; +} Pixel; + +/// Tile handle/index. +typedef uint16_t Tile; -- cgit v1.2.3