diff --git a/inc/map.h b/inc/map.h
index 00212d04..77311bd1 100644
--- a/inc/map.h
+++ b/inc/map.h
@@ -31,6 +31,41 @@
#include "vdp_tile.h"
#include "pal.h"
+// forward
+typedef struct Map Map;
+
+/**
+ * \brief
+ * Map data update type
+ */
+typedef enum
+{
+ ROW_UPDATE, /** tilemap row update **/
+ COLUMN_UPDATE /** tilemap column update **/
+} MapUpdateType;
+
+/**
+ * \brief
+ * Map data patch callback.
+ * It's used to modify/patch map data (for destructible blocks for instance) before sending it to VRAM.
+ *
+ * \param map
+ * source Map structure containing map information.
+ * \param buf
+ * buffer containing the tilemap data to patch
+ * \param x
+ * tile X start update position
+ * \param y
+ * tile Y start update position
+ * \param updateType
+ * map data update type:
+ * - ROW_UPDATE (tilemap row update)
+ * - COLUMN_UPDATE (tilemap column update)
+ * \param size
+ * size of the buffer (tilemap width or height depending we are on a row or column update type)
+ */
+typedef void MapDataPatchCallback(Map *map, u16 *buf, u16 x, u16 y, MapUpdateType updateType, u16 size);
+
/**
* \brief
@@ -87,7 +122,6 @@ typedef struct
u16* blockRowOffsets;
} MapDefinition;
-
/**
* \brief
* Map structure containing information for large background/plane update based on #MapDefinition
@@ -124,13 +158,17 @@ typedef struct
* internal
* \param lastYT
* internal
+ * \param hScrollTable
+ * internal
+ * \param vScrollTable
+ * internal
* \param prepareMapDataColumnCB
* internal
* \param prepareMapDataRowCB
* internal
- * \param hScrollTable
+ * \param patchMapDataColumnCB
* internal
- * \param vScrollTable
+ * \param patchMapDataRowCB
* internal
* \param getMetaTileCB
* internal
@@ -161,12 +199,11 @@ typedef struct Map
u16 lastYT;
u16 hScrollTable[240];
u16 vScrollTable[20];
- void (*prepareMapDataColumnCB)(struct Map *map, u16 *bufCol1, u16 *bufCol2, u16 xm, u16 ym, u16 height);
- void (*prepareMapDataRowCB)(struct Map *map, u16 *bufRow1, u16 *bufRow2, u16 xm, u16 ym, u16 width);
- void (*patchMapDataColumnCB)(struct Map *map, u16 *buf, u16 x, u16 y, u16 height);
- void (*patchMapDataRowCB)(struct Map *map, u16 *buf, u16 x, u16 y, u16 width);
- u16 (*getMetaTileCB)(struct Map *map, u16 x, u16 y);
- void (*getMetaTilemapRectCB)(struct Map *map, u16 x, u16 y, u16 w, u16 h, u16* dest);
+ void (*prepareMapDataColumnCB)(Map *map, u16 *bufCol1, u16 *bufCol2, u16 xm, u16 ym, u16 height);
+ void (*prepareMapDataRowCB)(Map *map, u16 *bufRow1, u16 *bufRow2, u16 xm, u16 ym, u16 width);
+ MapDataPatchCallback* mapDataPatchCB;
+ u16 (*getMetaTileCB)(Map *map, u16 x, u16 y);
+ void (*getMetaTilemapRectCB)(Map *map, u16 x, u16 y, u16 w, u16 h, u16* dest);
} Map;
@@ -211,7 +248,7 @@ void MAP_release(Map* map);
* SYS_doVBlankProcess() in between.
*
* \param map
- * Map structure containing map information.
+ * source Map structure containing map information.
* \param x
* view position X we want to scroll on
* \param y
@@ -225,7 +262,7 @@ void MAP_scrollTo(Map* map, u32 x, u32 y);
* Exactly as #MAP_scrollTo(..) except we can force complete map drawing
*
* \param map
- * Map structure containing map information.
+ * source Map structure containing map information.
* \param x
* view position X we want to scroll on
* \param y
@@ -347,6 +384,23 @@ void MAP_getMetaTilemapRect(Map* map, u16 x, u16 y, u16 w, u16 h, u16* dest);
*/
void MAP_getTilemapRect(Map* map, u16 x, u16 y, u16 w, u16 h, bool column, u16* dest);
+/**
+ * \brief
+ * Set the callback function to patch tilemap data.
+ * Note that you need to set
+ *
+ * The method will be called when a new tilemap row / column is ready to be send to the VDP.
+ * You can use this callback to modify the tilemap data before sending it to VRAM.
+ * It can be useful, for instance, to implement destructibles blocks.
+ *
+ * \param map
+ * source Map structure we want to set the patch data callback for.
+ * \param CB
+ * Callback to use to patch the new tilemap data (set to NULL by default = no callback).
+ * See declaration of #MapDataPatchCallback to get information about the callback parameters.
+ */
+void MAP_setDataPatchCallback(Map* map, MapDataPatchCallback *CB);
+
/**
* \brief
* Override the system (VDP) plane size for this map (should be called after MAP_create(..))
diff --git a/lib/libmd.a b/lib/libmd.a
index ec51375c..41d62470 100644
Binary files a/lib/libmd.a and b/lib/libmd.a differ
diff --git a/src/map.c b/src/map.c
index 1d14e9a8..bdd740f2 100644
--- a/src/map.c
+++ b/src/map.c
@@ -193,9 +193,8 @@ Map* NO_INLINE MAP_create(const MapDefinition* mapDef, VDPPlane plane, u16 baseT
}
}
- // patch callbacks
- result->patchMapDataColumnCB = NULL;
- result->patchMapDataRowCB = NULL;
+ // patch callback
+ result->mapDataPatchCB = NULL;
return result;
}
@@ -501,10 +500,10 @@ static void prepareMapDataColumn(Map *map, u16 *bufCol1, u16 *bufCol2, u16 xm, u
map->prepareMapDataColumnCB(map, bufCol1, bufCol2, xm, ym, height);
// patch data callback set ?
- if (map->patchMapDataColumnCB != NULL)
+ if (map->mapDataPatchCB != NULL)
{
- map->patchMapDataColumnCB(map, bufCol1, (xm * 2) + 0, ym * 2, height * 2);
- map->patchMapDataColumnCB(map, bufCol2, (xm * 2) + 1, ym * 2, height * 2);
+ map->mapDataPatchCB(map, bufCol1, (xm * 2) + 0, ym * 2, COLUMN_UPDATE, height * 2);
+ map->mapDataPatchCB(map, bufCol2, (xm * 2) + 1, ym * 2, COLUMN_UPDATE, height * 2);
}
#ifdef MAP_PROFIL
@@ -522,10 +521,10 @@ static void prepareMapDataRow(Map* map, u16 *bufRow1, u16 *bufRow2, u16 xm, u16
map->prepareMapDataRowCB(map, bufRow1, bufRow2, xm, ym, width);
// patch data callback set ?
- if (map->patchMapDataRowCB != NULL)
+ if (map->mapDataPatchCB != NULL)
{
- map->patchMapDataRowCB(map, bufRow1, xm * 2, (ym * 2) + 0, width * 2);
- map->patchMapDataRowCB(map, bufRow2, xm * 2, (ym * 2) + 1, width * 2);
+ map->mapDataPatchCB(map, bufRow1, xm * 2, (ym * 2) + 0, ROW_UPDATE, width * 2);
+ map->mapDataPatchCB(map, bufRow2, xm * 2, (ym * 2) + 1, ROW_UPDATE, width * 2);
}
#ifdef MAP_PROFIL
@@ -1904,6 +1903,12 @@ static void getMetaTilemapRect_MTI16_BI16(Map* map, u16 x, u16 y, u16 w, u16 h,
}
+void MAP_setDataPatchCallback(Map* map, MapDataPatchCallback *CB)
+{
+ map->mapDataPatchCB = CB;
+}
+
+
void MAP_overridePlaneSize(Map* map, u16 w, u16 h)
{
// only 32, 64 or 128 accepted here