Skip to content

Commit

Permalink
Added the new MAP patch data callback allowing easier map data patching
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephane-D committed Sep 28, 2024
1 parent ee06499 commit 5dd98a4
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 20 deletions.
76 changes: 65 additions & 11 deletions inc/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.<br>
* 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:<br>
* - ROW_UPDATE (tilemap row update)<br>
* - COLUMN_UPDATE (tilemap column update)<br>
* \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
Expand Down Expand Up @@ -87,7 +122,6 @@ typedef struct
u16* blockRowOffsets;
} MapDefinition;


/**
* \brief
* Map structure containing information for large background/plane update based on #MapDefinition
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;


Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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.<br>
* Note that you need to set
*<br>
* The method will be called when a new tilemap row / column is ready to be send to the VDP.<br>
* You can use this callback to modify the tilemap data before sending it to VRAM.<br>
* 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).<br>
* 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(..))<br>
Expand Down
Binary file modified lib/libmd.a
Binary file not shown.
23 changes: 14 additions & 9 deletions src/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

2 comments on commit 5dd98a4

@D0NM
Copy link
Contributor

@D0NM D0NM commented on 5dd98a4 Oct 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! It might be useful
Hope it doesn't slow down the engine.

@Stephane-D
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you don't use the feature it barely costs anything but when used it does cost quite a bit depending what you're doing in the callback.

Please sign in to comment.