/* Copyright (c) 2023 Alex Diener This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Alex Diener alex@ludobloom.com */ #ifndef __TileMapEditData_H__ #define __TileMapEditData_H__ #include "serialization/DeserializationContext.h" #include "serialization/SerializationContext.h" #include "tileset/TilesetEditData.h" #include "utilities/HashTable.h" #include #define TILE_MAP_EDIT_DATA_FORMAT_TYPE "tilemap_edit" #define TILE_MAP_EDIT_DATA_FORMAT_VERSION 0 #define TILE_MAP_DIMENSION_MAX 2048 #define TILE_MAP_LAYER_COUNT_MAX 64 #define TILE_MAP_SCHEMA_KEY_TILE_MAP ((uint32_t) -1) #define TILE_MAP_SCHEMA_KEY_TILE_MAP_LAYER ((uint32_t) -2) typedef uint32_t TileMapID; typedef struct TileInstance { TileID tileID; DataHashTable * metadata; } TileInstance; typedef struct TileInstanceGrid { Vector2u size; TileInstance * tileInstances; } TileInstanceGrid; typedef struct TileMapEditLayer { char * name; Vector2i offset; bool visible; bool writeEnabled; float opacity; TileInstanceGrid grid; DataHashTable * metadata; } TileMapEditLayer; typedef struct TileMapEditData { TileMapID identifier; char * name; Vector2u size; Vector2i origin; unsigned int layerCount; TileMapEditLayer * layers; HashTable * schemasInUse; DataHashTable * metadata; } TileMapEditData; // Takes ownership of all layers' contents if copy is false // Does not add schemas for any tiles. If tiles in layers contain metadata, add manually with TileMapEditData_setTileSchema(). // Layer metadata schemas are assumed to match the tileset's layer schema. Don't add layers with mismatched metadata. TileMapEditData * TileMapEditData_create(TileMapID identifier, const char * name, TilesetEditData * tileset, Vector2u size, Vector2i origin, unsigned int layerCount, TileMapEditLayer * layers, bool copy); TileMapEditData * TileMapEditData_copy(TileMapEditData * tileMap); void TileMapEditData_dispose(TileMapEditData * tileMap); void TileMapEditData_serializeMinimal(TileMapEditData * tileMap, compat_type(SerializationContext *) serializationContext); void TileMapEditData_serialize(TileMapEditData * tileMap, compat_type(SerializationContext *) serializationContext); TileMapEditData * TileMapEditData_deserializeMinimal(compat_type(DeserializationContext *) deserializationContext, uint16_t formatVersion); TileMapEditData * TileMapEditData_deserialize(compat_type(DeserializationContext *) deserializationContext); // Takes ownership of all layer contents // Does not add schemas for any tiles. If tiles in layers contain metadata, add manually with TileMapEditData_setTileSchema(). // Layer metadata schemas are assumed to match the tile map's layer schema in use. Don't add layers with mismatched metadata. void TileMapEditData_addLayer(TileMapEditData * tileMap, TileMapEditLayer layer); void TileMapEditData_insertLayer(TileMapEditData * tileMap, unsigned int layerIndex, TileMapEditLayer layer); void TileMapEditData_removeLayerAtIndex(TileMapEditData * tileMap, unsigned int layerIndex); void TileMapEditData_reorderLayer(TileMapEditData * tileMap, unsigned int fromLayerIndex, unsigned int toLayerIndex); TileMapEditLayer TileMapEditData_newLayer(TileMapEditData * tileMap); TileMapEditLayer TileMapEditLayer_copy(TileMapEditLayer * layer); // key can be a tile ID, TILE_MAP_SCHEMA_KEY_TILE_MAP, or TILE_MAP_SCHEMA_KEY_TILE_MAP_LAYER DataValueSchema * TileMapEditData_getSchemaInUse(TileMapEditData * tileMap, uint32_t key); // Has no effect if the schema is already known; check directly in schemasInUse before calling // Note: TileMapEditData_getSchemaInUse() returns NULL both for schemas known and unassigned and for schemas not known, so // schemasInUse must be checked directly in case of entries with a NULL value. void TileMapEditData_setTileSchema(TileMapEditData * tileMap, uint32_t key, DataValueSchema * schema); TileInstanceGrid TileInstanceGrid_create(unsigned int width, unsigned int height); TileInstanceGrid TileInstanceGrid_copy(TileInstanceGrid * grid); void TileInstanceGrid_dispose(TileInstanceGrid * grid); bool TileInstanceGrid_isEqual(TileInstanceGrid * grid1, TileInstanceGrid * grid2); // Sets all tiles to tileID and all metadata to NULL void TileInstanceGrid_clear(TileInstanceGrid * grid, TileID tileID); // Copies a region of source to target, of a size specified by width and height, from an offset specified by sourceX and sourceY, to // an offset specified by targetX and targetY. The copied region is clipped if it would go outside either source or target's bounds. void TileInstanceGrid_copyTiles(TileInstanceGrid * target, TileInstanceGrid * source, int sourceX, int sourceY, int targetX, int targetY, unsigned int width, unsigned int height); // Similar to TileMap_copyTiles(), but doesn't overwrite target where source's tileID is 0 void TileInstanceGrid_composite(TileInstanceGrid * target, TileInstanceGrid * source, int sourceX, int sourceY, int targetX, int targetY, unsigned int width, unsigned int height); #endif