changeset 1785:7ec862ed6514

Implement some of the necessary search helper functions related to map block parsing and so on.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 29 Oct 2017 04:56:54 +0200
parents 9ee269ae165d
children eb98e57d3969
files mapsearch.c
diffstat 1 files changed, 158 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mapsearch.c	Sun Oct 29 04:52:50 2017 +0200
+++ b/mapsearch.c	Sun Oct 29 04:56:54 2017 +0200
@@ -417,6 +417,164 @@
 }
 
 
+void mapBlockGetDimensions(const unsigned char *data, const size_t len, int *width, int *height)
+{
+    size_t offs = 0;
+    int x = 0, x2 = 0;
+    BOOL flag = TRUE;
+
+    *height = 0;
+    *width = -1;
+
+    while (offs < len)
+    {
+        const unsigned char c = data[offs++];
+        if (c == '\n')
+        {
+            if (x == 0)
+                return;
+
+            if (x > *width)
+                *width = x;
+
+            x = x2 = 0;
+            flag = TRUE;
+        }
+        else
+        {
+            if (flag)
+            {
+                (*height)++;
+                flag = FALSE;
+            }
+            x2++;
+            if (c != ' ')
+                x = x2;
+        }
+    }
+
+    if (x > 0)
+        (*height)++;
+
+    if (x > *width)
+        *width = x;
+}
+
+
+BOOL mapBlockParse(const unsigned char *data, const size_t len, MapBlock *res)
+{
+    unsigned char *dp = res->data;
+    size_t offs = 0;
+    BOOL flag = FALSE;
+    int x = 0, y = 0;
+
+    while (offs < len && y < res->height)
+    {
+        const unsigned char c = data[offs++];
+        if (c == '\n')
+        {
+            if (x == 0)
+                return TRUE;
+            else
+            if (x != res->width)
+            {
+                THERR("Broken block line #%d width %d != %d!\n",
+                    y, x, res->width);
+
+                return FALSE;
+            }
+            flag = TRUE;
+        }
+        else
+        {
+            if (flag)
+            {
+                x = 0;
+                y++;
+                dp = res->data + (y * res->scansize);
+                flag = FALSE;
+            }
+            dp[x++] = c;
+
+            if (x > res->scansize)
+            {
+                THERR("Broken block line #%d width %d > scansize %d!\n",
+                    y, x, res->scansize);
+
+                return FALSE;
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+
+BOOL mapBlockFindCenter(const MapBlock *block, const char *symbols, int *cx, int *cy, const int tolerance)
+{
+    const int
+        x0 = (block->width * tolerance) / 100,
+        x1 = (block->width * (100 - tolerance)) / 100,
+        y0 = (block->height * tolerance) / 100,
+        y1 = (block->height * (100 - tolerance)) / 100;
+
+    for (int yc = 0; yc < block->height; yc++)
+    {
+        unsigned char *dp = block->data + (yc * block->scansize);
+        for (int xc = 0; xc < block->width; xc++)
+        {
+            if (xc >= x0 && xc <= x1 &&
+                yc >= y0 && yc <= y1 &&
+                strchr(symbols, dp[xc]) != NULL)
+            {
+                *cx = xc;
+                *cy = yc;
+                return TRUE;
+            }
+        }
+    }
+
+    return FALSE;
+}
+
+
+double mapMatchBlock(const MapBlock *map, const MapBlock *match, int ox, int oy, int fillCh, BOOL hardDrop)
+{
+    int n, k;
+
+    n = k = 0;
+    for (int y = 0; y < match->height; y++)
+    {
+        unsigned char *dp = match->data + (y * match->scansize);
+        for (int x = 0; x < match->width; x++)
+        {
+            int c1, c2;
+            const int
+                dx = ox + x,
+                dy = oy + y;
+
+            k++;
+
+            if (dx >= 0 && dx < map->width && dy >= 0 && dy < map->height)
+                c2 = map->data[(dy * map->scansize) + dx];
+            else
+                c2 = fillCh;
+
+            c1 = dp[x];
+
+            if (c1 == 0 || c1 == c2)
+                n++;
+            else
+            if (hardDrop)
+                return -1;
+        }
+    }
+
+    if (k > 0)
+        return ((double) n * 100.0f) / (double) k;
+    else
+        return 0.0f;
+}
 
 
 int mapLWSCallback(struct lws *wsi,