# HG changeset patch # User Matti Hamalainen # Date 1509245814 -7200 # Node ID 7ec862ed65147302c10e17485d399f21096f1c30 # Parent 9ee269ae165d8778983e90d3225d26ba370388dc Implement some of the necessary search helper functions related to map block parsing and so on. diff -r 9ee269ae165d -r 7ec862ed6514 mapsearch.c --- 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,