[3.4RC - Win32 client] Minimap with tiles

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • PowerWyrm
    Prophet
    • Apr 2008
    • 2986

    [3.4RC - Win32 client] Minimap with tiles

    Displaying the minimap is very slow when there are a lot of tiles to display (large window/small tiles). This only happens when using the Win32 client -- it's instantaneous when using the SDL client under Windows. This is probably because the SDL surface is created with each window, when the Win DC is recreated each time a tile is displayed...
    PWMAngband variant maintainer - check https://github.com/draconisPW/PWMAngband (or http://www.mangband.org/forum/viewforum.php?f=9) to learn more about this new variant!
  • PowerWyrm
    Prophet
    • Apr 2008
    • 2986

    #2
    I just discovered that the code in Term_pict_win() could be massively optimized by doing the following:

    Code:
    	/* Draw attr/char pairs */
    	for (i = n-1; i >= 0; i--, x2 -= w2) {
    		byte a = ap[i];
    		wchar_t c = cp[i];
    
    		/* Extract picture */
    		int row = (a & 0x7F);
    		int col = (c & 0x7F);
    
    		/* Location of bitmap cell */
    		x1 = col * w1;
    		y1 = row * h1;
    
    		if (hdcMask) {
    			[COLOR="Red"][B]/* Default background to darkness */
    			x3 = y3 = 0;
    
    			/* Use the terrain picture only if mapped */
    			if (tap[i] & 0x80) {[/B][/COLOR]
    			x3 = (tcp[i] & 0x7F) * w1;
    			y3 = (tap[i] & 0x7F) * h1;
    			[COLOR="red"][B]}[/B][/COLOR]
    
    			/* Perfect size */
    			if ((w1 == tw2) && (h1 == th2)) {
    				/* Copy the terrain picture from the bitmap to the window */
    				[COLOR="red"][B]if (x3 || y3)[/B][/COLOR] BitBlt(hdc, x2, y2, tw2, th2, hdcSrc, x3, y3, SRCCOPY);
    
    				/* Only draw if terrain and overlay are different */
    				if ((x1 != x3) || (y1 != y3)) {
    					/* Mask out the tile */
    					[COLOR="red"][B]if (x3 || y3)[/B][/COLOR] BitBlt(hdc, x2, y2, tw2, th2, hdcMask, x1, y1, SRCAND);
    
    					/* Draw the tile */
    					[COLOR="red"][B]if (x3 || y3)[/B][/COLOR] BitBlt(hdc, x2, y2, tw2, th2, hdcSrc, x1, y1, SRCPAINT);
    					[COLOR="red"][B]else BitBlt(hdc, x2, y2, tw2, th2, hdcSrc, x1, y1, SRCCOPY);[/B][/COLOR]
    				}
    
    			/* Need to stretch */
    			} else {
    				/* Set the correct mode for stretching the tiles */
    				SetStretchBltMode(hdc, COLORONCOLOR);
    
    				/* Copy the terrain picture from the bitmap to the window */
    				[COLOR="red"][B]if (x3 || y3)[/B][/COLOR] StretchBlt(hdc, x2, y2, tw2, th2, hdcSrc, x3, y3, w1, h1, SRCCOPY);
    
    				/* Only draw if terrain and overlay are different */
    				if ((x1 != x3) || (y1 != y3)) {
    					/* Mask out the tile */
    					[COLOR="red"][B]if (x3 || y3)[/B][/COLOR] StretchBlt(hdc, x2, y2, tw2, th2, hdcMask, x1, y1, w1, h1, SRCAND);
    
    					/* Draw the tile */
    					[COLOR="red"][B]if (x3 || y3)[/B][/COLOR] StretchBlt(hdc, x2, y2, tw2, th2, hdcSrc, x1, y1, w1, h1, SRCPAINT);
    					[COLOR="red"][B]else StretchBlt(hdc, x2, y2, tw2, th2, hdcSrc, x1, y1, w1, h1, SRCCOPY);[/B][/COLOR]
    				}
    			}
    		} else {
    			/* Perfect size */
    			if ((w1 == tw2) && (h1 == th2)) {
    				/* Copy the picture from the bitmap to the window */
    				BitBlt(hdc, x2, y2, tw2, th2, hdcSrc, x1, y1, SRCCOPY);
    
    			/* Need to stretch */
    			} else {
    				/* Set the correct mode for stretching the tiles */
    				SetStretchBltMode(hdc, COLORONCOLOR);
    
    				/* Copy the picture from the bitmap to the window */
    				StretchBlt(hdc, x2, y2, tw2, th2, hdcSrc, x1, y1, w1, h1, SRCCOPY);
    			}
    		}
    	}
    With this code, the minimap displays itself in 60ms instead of 500ms when using David Gervais tiles. And redrawing the screen with David Gervais tiles when playing in fullscreen mode takes 500ms instead of 4 seconds. And this also fixed the problem with unmapped tiles not refreshed properly...
    PWMAngband variant maintainer - check https://github.com/draconisPW/PWMAngband (or http://www.mangband.org/forum/viewforum.php?f=9) to learn more about this new variant!

    Comment

    • fizzix
      Prophet
      • Aug 2009
      • 3025

      #3
      I'll try out this patch, and let you know what I find out.

      Comment

      • PowerWyrm
        Prophet
        • Apr 2008
        • 2986

        #4
        In fact, the slowdown is caused by calling Term_putch() to display the minimap tiles. Term_putch() queues a tile with transparency = 0, which is inefficient in the case of the Win32 client, since the original code first blits the terrain tile, then ANDs the overlay mask and finally ORs the overlay tile. In this case, the costly StretchBlt() function is called three times to do 0 AND something...

        Using Term_queue_char(tile, tile) in display_map() instead of the previous code should also do the trick.
        PWMAngband variant maintainer - check https://github.com/draconisPW/PWMAngband (or http://www.mangband.org/forum/viewforum.php?f=9) to learn more about this new variant!

        Comment

        Working...
        😀
        😂
        🥰
        😘
        🤢
        😎
        😞
        😡
        👍
        👎