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);