Files
libakgl/include/akgl/tilemap.h

113 lines
4.3 KiB
C
Raw Normal View History

#ifndef _TILEMAP_H_
#define _TILEMAP_H_
#include "actor.h"
#include "staticstring.h"
#include <jansson.h>
#define AKGL_TILEMAP_MAX_WIDTH 512
#define AKGL_TILEMAP_MAX_HEIGHT 512
#define AKGL_TILEMAP_MAX_LAYERS 16
#define AKGL_TILEMAP_MAX_TILESETS 16
#define AKGL_TILEMAP_MAX_TILES_PER_IMAGE 65536
#define AKGL_TILEMAP_MAX_TILESET_NAME_SIZE 512
#define AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE 512
#define AKGL_TILEMAP_MAX_OBJECT_NAME_SIZE 512
#define AKGL_TILEMAP_MAX_OBJECTS_PER_LAYER 128
#define AKGL_TILEMAP_OBJECT_TYPE_ACTOR 1
#define AKGL_TILEMAP_LAYER_TYPE_TILES 1
#define AKGL_TILEMAP_LAYER_TYPE_OBJECTS 2
typedef struct {
float x;
float y;
int gid;
int id;
int height;
int width;
int rotation;
int type;
bool visible;
akgl_Actor *actorptr;
char name[AKGL_TILEMAP_MAX_OBJECT_NAME_SIZE];
} akgl_TilemapObject;
typedef struct {
short type;
float opacity;
bool visible;
int height;
int width;
int x;
int y;
int id;
int data[AKGL_TILEMAP_MAX_WIDTH * AKGL_TILEMAP_MAX_HEIGHT];
akgl_TilemapObject objects[AKGL_TILEMAP_MAX_OBJECTS_PER_LAYER];
} akgl_TilemapLayer;
typedef struct {
int columns;
int firstgid;
char imagefilename[AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE];
int imageheight;
int imagewidth;
char name[AKGL_TILEMAP_MAX_TILESET_NAME_SIZE];
SDL_Texture *texture;
// Use this as a lookup table instead of storing tiles
// in individual textures to blit them from a single
// texture at runtime
// FIXME: This is probably not very efficient. For a map
// with a single tileset it makes sense. For a map with
// multiple tilesets you may have set A start at firstgid 1
// and have 1728 tiles. Set B may start at firstgid 1729 and
// have 1728 more tiles. This means Set B has 1728 empty
// tile_offsets[] entries before firstgid 1729 because of the
// way akgl_tilemap_load_tilesets() works. This is really inefficient
// and should be improved in the future, and will eventually
// lead to premature exhaustion of AKGL_TILEMAP_MAX_TILES_PER_IMAGE
// because set D or E may only have 64 tiles but they may be
// at the upper end of the array bound already because of this.
int tile_offsets[AKGL_TILEMAP_MAX_TILES_PER_IMAGE][2];
int tilecount;
int tileheight;
int tilewidth;
int spacing;
int margin;
} akgl_Tileset;
typedef struct {
int tilewidth;
int tileheight;
int width;
int height;
int numlayers;
int orientation; // 0 = orthogonal, 1 = isometric
int numtilesets;
akgl_Tileset tilesets[AKGL_TILEMAP_MAX_TILESETS];
akgl_TilemapLayer layers[AKGL_TILEMAP_MAX_LAYERS];
} akgl_Tilemap;
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load(char *fname, akgl_Tilemap *dest);
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_draw(SDL_Renderer *renderer, akgl_Tilemap *dest, SDL_FRect *viewport, int layeridx);
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_draw_tileset(SDL_Renderer *renderer, akgl_Tilemap *dest, int tilesetidx);
/*
* These functions are part of the internal API and should not be called by the user.
* They are only exposed here for unit testing.
*/
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_tilemap_property(json_t *obj, char *key, char *type, json_t **dest);
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_properties_string(json_t *obj, char *key, akgl_String **dest);
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_properties_integer(json_t *obj, char *key, int *dest);
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_compute_tileset_offsets(akgl_Tilemap *dest, int tilesetidx);
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_layer_objects(akgl_Tilemap *dest, json_t *root, int layerid);
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_layer_tile(akgl_Tilemap *dest, json_t *root, int layerid);
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_layers(akgl_Tilemap *dest, json_t *root);
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_tilesets_each(json_t *tileset, akgl_Tilemap *dest, int tsidx);
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_tilesets(akgl_Tilemap *dest, json_t *root);
#endif //_TILEMAP_H_