Mercurial > hg > batmud > maputils
changeset 32:c41ec03eac99
Updates, fixes
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 11 Dec 2006 05:33:47 +0000 |
parents | 25e473a82ce3 |
children | ac2d809a3dda |
files | mkspecial.c |
diffstat | 1 files changed, 115 insertions(+), 54 deletions(-) [+] |
line wrap: on
line diff
--- a/mkspecial.c Sun Dec 10 20:10:38 2006 +0000 +++ b/mkspecial.c Mon Dec 11 05:33:47 2006 +0000 @@ -301,7 +301,7 @@ for (oy = -(b->h); oy < (map->h + b->h); oy++) for (ox = -(b->w); ox < (map->w + b->w); ox++) { - v = matchBlock(map, b, ox, oy, TRUE); + v = matchBlock(map, b, ox, oy, FALSE); if (v >= *m) { *m = v; *x = ox; @@ -314,11 +314,23 @@ } +void getWorldSize(mapblock_t *tmp, DINT *worldX0, DINT *worldY0, DINT *worldX1, DINT *worldY1) +{ + if (tmp->x < *worldX0) *worldX0 = tmp->x; + if ((tmp->x + tmp->w) > *worldX1) *worldX1 = (tmp->x + tmp->w); + + if (tmp->y < *worldY0) *worldY0 = tmp->y; + if ((tmp->y + tmp->h) > *worldY1) *worldY1 = (tmp->y + tmp->h); +} + + int main(int argc, char *argv[]) { DBOOL isOK; - DINT i, offsetX, offsetY, currRounds, nmapBlocks, currBlocks; - mapblock_t *map = NULL, *initialMap = NULL; + DINT i, currRounds, nmapBlocks, currBlocks, + worldX0, worldY0, worldX1, worldY1, + offsetX, offsetY; + mapblock_t *worldMap = NULL, *initialMap = NULL; mapblock_t **mapBlocks = NULL; progName = argv[0]; @@ -378,16 +390,29 @@ THMSG(1, "Total of %d mapblocks read.\n", nmapBlocks); + if (nmapBlocks <= 0) { + THERR("No mapblocks, nothing to do.\n"); + exit(11); + } + /* ALGORITHM * --------- if (initial map IS available) { find first initial match > threshold - compute block coordinate offset - } else { - just use 0,0 as coordinate offset + save coordinates of map relative to the matched block } + find dimensions of the world map: + for (each block in list) { + if (block->x < mapx0) mapx0 = block->x; else + if (block->x+block->w > mapx1) mapx1 = block->x+block->w; + ... + } + + allocate map + + start placing blocks: for (n = 0; n < rounds; n++) { for (each block in list) { if (check match % at given coordinates > threshold) @@ -397,66 +422,99 @@ if (all blocks placed) break } */ - /* Get dimensions */ - - offsetX = offsetY = 0; - + + + /* If initial map is available, find a match and determine coords */ if (initialMap) { - DFLOAT mv = optMatchInit; - map = initialMap; - isOK = FALSE; + DINT blockSkip = 256; + DFLOAT mv; + mapblock_t *resBlock = NULL; THMSG(1, "Matching with initial map ...\n"); + + isOK = FALSE; + currRounds = 0; + while ((currRounds++ < optRounds) && !isOK) { + DINT usedBlocks; - for (i = 0; i < nmapBlocks && !isOK; i++) { - THPRINT(1, "%d%%..", (i * 100) / nmapBlocks); + /* Get number of used blocks */ + for (usedBlocks = i = 0; i < nmapBlocks; i++) + if (mapBlocks[i]->mark) usedBlocks++; - if (blockSearchBrute(map, mapBlocks[i], &offsetX, &offsetY, &mv)) { - THMSG(1, "Found init point at [%d] %d,%d (%1.3f%%)\n", - i, offsetX, offsetY, mv); + /* Print out status information */ + THPRINT(2, "#%d (%d) [%d/%d]: ", + currRounds, blockSkip, usedBlocks, nmapBlocks); + + /* Search */ + for (isOK = FALSE, i = 0; i < nmapBlocks && !isOK; i += blockSkip) + if (!mapBlocks[i]->mark) { + mv = optMatchInit; + resBlock = mapBlocks[i]; - if (putBlock(&map, mapBlocks[i], offsetX, offsetY, 15 /* FIXME */) < 0) { - THERR("putBlock(%d, %d, %d) failed!\n", - offsetX, offsetY, i); - exit(9); + THPRINT(1, "."); + resBlock->mark = TRUE; + + if (blockSearchBrute(initialMap, resBlock, + &offsetX, &offsetY, &mv)) { + THMSG(1, "Found matching block #%d (%1.3f%%)\n", i, mv); + isOK = TRUE; } - - isOK = TRUE; } + + /* Make blockskip smaller, next round */ + THPRINT(2, "\n"); + if (blockSkip >= 2) + blockSkip /= 2; + else + break; } if (!isOK) { THERR("No matches initmap <-> blocks. Need more data.\n"); exit(6); } - - } else if (nmapBlocks > 0) { - mapblock_t *tmp; - - tmp = mapBlocks[0]; - - if ((map = allocBlock(tmp->w * optMapFactor, tmp->h * optMapFactor)) == NULL) { - THERR("Could not allocate initial map.\n"); - exit(5); - } - - offsetX = (map->w / 2) - (tmp->w / 2); - offsetY = (map->h / 2) - (tmp->h / 2); - - putBlockDo(map, tmp, offsetX, offsetY); -/* - offsetX -= tmp->x; - offsetY -= tmp->y; -*/ + + /* Compute inital map offset shit */ + initialMap->x = -offsetX + resBlock->x; + initialMap->y = -offsetY + resBlock->y; } - if (!map) { - THERR("Initial map could not be formed, no input.\n"); + /* Clear marks */ + for (i = 0; i < nmapBlocks; i++) + mapBlocks[i]->mark = FALSE; + + + /* Get world dimensions */ + worldX0 = worldY0 = worldX1 = worldY1 = 0; + for (i = 0; i < nmapBlocks; i++) + getWorldSize(mapBlocks[i], &worldX0, &worldY0, &worldX1, &worldY1); + + if (initialMap) + getWorldSize(initialMap, &worldX0, &worldY0, &worldX1, &worldY1); + + /* Compute offsets, allocate world map */ + /* FIXME: check dimensions */ + offsetX = -worldX0; + offsetY = -worldY0; + + if ((worldMap = allocBlock((worldX1 - worldX0 + 1), (worldY1 - worldY0 + 1))) == NULL) { + THERR("Error allocating world map!\n"); exit(4); } + + /* Place optional initial map */ + if (initialMap) { + if (putBlock(&worldMap, initialMap, offsetX+initialMap->x, offsetY+initialMap->y, 1) < 0) { + THERR("Initial map putBlock() failed!\n"); + exit(9); + } + } - THMSG(1, "Initialized initial map of (%d x %d)\n", map->w, map->h); + THMSG(1, "Initialized world map of (%d x %d), offset (%d, %d)\n", + worldMap->w, worldMap->h, offsetX, offsetY); + + /* Start placing blocks */ currRounds = 0; isOK = FALSE; while ((currRounds++ < optRounds) && !isOK) { @@ -470,7 +528,7 @@ THPRINT(2, "#%d [%d/%d]: ", currRounds, usedBlocks, nmapBlocks); - /* Search and match blocks */ + /* Place and match blocks */ isOK = TRUE; currBlocks = 0; for (i = 0; i < nmapBlocks && currBlocks < optReset; i++) { @@ -482,8 +540,8 @@ isOK = FALSE; - if (matchBlock(map, tmp, qx, qy, TRUE) >= optMatch) { - if (putBlock(&map, tmp, qx, qy, 15) < 0) { + if (matchBlock(worldMap, tmp, qx, qy, TRUE) >= optMatch) { + if (putBlock(&worldMap, tmp, qx, qy, 1) < 0) { THERR("putBlock(%d, %d, %d) failed!\n", offsetX, offsetY, i); exit(9); @@ -493,7 +551,9 @@ THPRINT(2, "X"); } else { THPRINT(2, "."); -#if 1 + +#if 0 + /* Debug unmatching blocks */ DCHAR mysti[512]; snprintf(mysti, sizeof(mysti), "[%d]: %d,%d (%d,%d)", @@ -501,7 +561,7 @@ fprintf(stderr, "\n--- %.30s ---\n", mysti); printBlock(stderr, tmp); fprintf(stderr, "---------\n"); - printBlock(stderr, map); + printBlock(stderr, worldMap); #endif } } @@ -512,11 +572,12 @@ /* Output generated map */ - if (map) { + if (worldMap) { DINT unusedBlocks; FILE *tmpFile; - THMSG(1, "Outputting generated map ...\n"); + THMSG(1, "Outputting generated map of (%d x %d) ...\n", + worldMap->w, worldMap->h); if (destFile == NULL) tmpFile = stdout; @@ -526,7 +587,7 @@ exit(1); } - printBlock(tmpFile, map); + printBlock(tmpFile, worldMap); fclose(tmpFile);