src/viewport.cpp
changeset 6423 8e10e79e0fd1
parent 6248 e4a2ed7e5613
child 6427 7dc1012757d8
equal deleted inserted replaced
6422:6679df1c05ba 6423:8e10e79e0fd1
    23 #include "variables.h"
    23 #include "variables.h"
    24 #include "train.h"
    24 #include "train.h"
    25 
    25 
    26 #define VIEWPORT_DRAW_MEM (65536 * 2)
    26 #define VIEWPORT_DRAW_MEM (65536 * 2)
    27 
    27 
    28 // XXX - maximum viewports is maximum windows - 2 (main toolbar + status bar)
    28 /* XXX - maximum viewports is maximum windows - 2 (main toolbar + status bar) */
    29 static ViewPort _viewports[25 - 2];
    29 static ViewPort _viewports[25 - 2];
    30 static uint32 _active_viewports;    ///< bitmasked variable where each bit signifies if a viewport is in use or not
    30 static uint32 _active_viewports;    ///< bitmasked variable where each bit signifies if a viewport is in use or not
    31 assert_compile(lengthof(_viewports) < sizeof(_active_viewports) * 8);
    31 assert_compile(lengthof(_viewports) < sizeof(_active_viewports) * 8);
    32 
    32 
    33 static bool _added_tile_sprite;
    33 static bool _added_tile_sprite;
    89 	byte unk16;
    89 	byte unk16;
    90 	byte zmin;
    90 	byte zmin;
    91 	byte zmax;
    91 	byte zmax;
    92 };
    92 };
    93 
    93 
    94 // Quick hack to know how much memory to reserve when allocating from the spritelist
    94 /* Quick hack to know how much memory to reserve when allocating from the spritelist
    95 // to prevent a buffer overflow.
    95  * to prevent a buffer overflow. */
    96 #define LARGEST_SPRITELIST_STRUCT ParentSpriteToDraw
    96 #define LARGEST_SPRITELIST_STRUCT ParentSpriteToDraw
    97 
    97 
    98 struct ViewportDrawer {
    98 struct ViewportDrawer {
    99 	DrawPixelInfo dpi;
    99 	DrawPixelInfo dpi;
   100 
   100 
   436 }
   436 }
   437 
   437 
   438 void DrawGroundSprite(SpriteID image, SpriteID pal)
   438 void DrawGroundSprite(SpriteID image, SpriteID pal)
   439 {
   439 {
   440 	if (_offset_ground_sprites) {
   440 	if (_offset_ground_sprites) {
   441 		// offset ground sprite because of foundation?
   441 		/* offset ground sprite because of foundation? */
   442 		AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y);
   442 		AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y);
   443 	} else {
   443 	} else {
   444 		_added_tile_sprite = true;
   444 		_added_tile_sprite = true;
   445 		DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z);
   445 		DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z);
   446 	}
   446 	}
   491 		return;
   491 		return;
   492 	}
   492 	}
   493 	ps = (ParentSpriteToDraw*)vd->spritelist_mem;
   493 	ps = (ParentSpriteToDraw*)vd->spritelist_mem;
   494 
   494 
   495 	if (vd->parent_list >= vd->eof_parent_list) {
   495 	if (vd->parent_list >= vd->eof_parent_list) {
   496 		// This can happen rarely, mostly when you zoom out completely
   496 		/* This can happen rarely, mostly when you zoom out completely
   497 		//  and have a lot of stuff that moves (and is added to the
   497 		 *  and have a lot of stuff that moves (and is added to the
   498 		//  sort-list, this function). To solve it, increase
   498 		 *  sort-list, this function). To solve it, increase
   499 		//  parent_list somewhere below to a higher number.
   499 		 *  parent_list somewhere below to a higher number.
   500 		// This can not really hurt you, it just gives some black
   500 		 * This can not really hurt you, it just gives some black
   501 		//  spots on the screen ;)
   501 		 *  spots on the screen ;) */
   502 		DEBUG(sprite, 0, "Out of sprite memory (parent_list)");
   502 		DEBUG(sprite, 0, "Out of sprite memory (parent_list)");
   503 		return;
   503 		return;
   504 	}
   504 	}
   505 
   505 
   506 	pt = RemapCoords(x, y, z);
   506 	pt = RemapCoords(x, y, z);
   644 static void DrawTileSelection(const TileInfo *ti)
   644 static void DrawTileSelection(const TileInfo *ti)
   645 {
   645 {
   646 	SpriteID image;
   646 	SpriteID image;
   647 	SpriteID pal;
   647 	SpriteID pal;
   648 
   648 
   649 	// Draw a red error square?
   649 	/* Draw a red error square? */
   650 	if (_thd.redsq != 0 && _thd.redsq == ti->tile) {
   650 	if (_thd.redsq != 0 && _thd.redsq == ti->tile) {
   651 		DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_TILE_RED_PULSATING, ti);
   651 		DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_TILE_RED_PULSATING, ti);
   652 		return;
   652 		return;
   653 	}
   653 	}
   654 
   654 
   655 	// no selection active?
   655 	/* no selection active? */
   656 	if (_thd.drawstyle == 0) return;
   656 	if (_thd.drawstyle == 0) return;
   657 
   657 
   658 	// Inside the inner area?
   658 	/* Inside the inner area? */
   659 	if (IS_INSIDE_1D(ti->x, _thd.pos.x, _thd.size.x) &&
   659 	if (IS_INSIDE_1D(ti->x, _thd.pos.x, _thd.size.x) &&
   660 			IS_INSIDE_1D(ti->y, _thd.pos.y, _thd.size.y)) {
   660 			IS_INSIDE_1D(ti->y, _thd.pos.y, _thd.size.y)) {
   661 		if (_thd.drawstyle & HT_RECT) {
   661 		if (_thd.drawstyle & HT_RECT) {
   662 			image = SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh];
   662 			image = SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh];
   663 			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE, ti);
   663 			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE, ti);
   664 		} else if (_thd.drawstyle & HT_POINT) {
   664 		} else if (_thd.drawstyle & HT_POINT) {
   665 			// Figure out the Z coordinate for the single dot.
   665 			/* Figure out the Z coordinate for the single dot. */
   666 			byte z = ti->z;
   666 			byte z = ti->z;
   667 			if (ti->tileh & SLOPE_N) {
   667 			if (ti->tileh & SLOPE_N) {
   668 				z += TILE_HEIGHT;
   668 				z += TILE_HEIGHT;
   669 				if (ti->tileh == SLOPE_STEEP_N) z += TILE_HEIGHT;
   669 				if (ti->tileh == SLOPE_STEEP_N) z += TILE_HEIGHT;
   670 			}
   670 			}
   671 			DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti->x, ti->y, z);
   671 			DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti->x, ti->y, z);
   672 		} else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) {
   672 		} else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) {
   673 			// autorail highlight piece under cursor
   673 			/* autorail highlight piece under cursor */
   674 			uint type = _thd.drawstyle & 0xF;
   674 			uint type = _thd.drawstyle & 0xF;
   675 			int offset;
   675 			int offset;
   676 
   676 
   677 			assert(type <= 5);
   677 			assert(type <= 5);
   678 
   678 
   686 			}
   686 			}
   687 
   687 
   688 			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
   688 			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
   689 
   689 
   690 		} else if (IsPartOfAutoLine(ti->x, ti->y)) {
   690 		} else if (IsPartOfAutoLine(ti->x, ti->y)) {
   691 			// autorail highlighting long line
   691 			/* autorail highlighting long line */
   692 			int dir = _thd.drawstyle & ~0xF0;
   692 			int dir = _thd.drawstyle & ~0xF0;
   693 			int offset;
   693 			int offset;
   694 			uint side;
   694 			uint side;
   695 
   695 
   696 			if (dir < 2) {
   696 			if (dir < 2) {
   712 			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
   712 			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
   713 		}
   713 		}
   714 		return;
   714 		return;
   715 	}
   715 	}
   716 
   716 
   717 	// Check if it's inside the outer area?
   717 	/* Check if it's inside the outer area? */
   718 	if (_thd.outersize.x &&
   718 	if (_thd.outersize.x &&
   719 			_thd.size.x < _thd.size.x + _thd.outersize.x &&
   719 			_thd.size.x < _thd.size.x + _thd.outersize.x &&
   720 			IS_INSIDE_1D(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) &&
   720 			IS_INSIDE_1D(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) &&
   721 			IS_INSIDE_1D(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) {
   721 			IS_INSIDE_1D(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) {
   722 		// Draw a blue rect.
   722 		/* Draw a blue rect. */
   723 		DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_SEL_TILE_BLUE, ti);
   723 		DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_SEL_TILE_BLUE, ti);
   724 		return;
   724 		return;
   725 	}
   725 	}
   726 }
   726 }
   727 
   727 
   732 	TileInfo ti;
   732 	TileInfo ti;
   733 	bool direction;
   733 	bool direction;
   734 
   734 
   735 	_cur_ti = &ti;
   735 	_cur_ti = &ti;
   736 
   736 
   737 	// Transform into tile coordinates and round to closest full tile
   737 	/* Transform into tile coordinates and round to closest full tile */
   738 	x = ((vd->dpi.top >> 1) - (vd->dpi.left >> 2)) & ~0xF;
   738 	x = ((vd->dpi.top >> 1) - (vd->dpi.left >> 2)) & ~0xF;
   739 	y = ((vd->dpi.top >> 1) + (vd->dpi.left >> 2) - 0x10) & ~0xF;
   739 	y = ((vd->dpi.top >> 1) + (vd->dpi.left >> 2) - 0x10) & ~0xF;
   740 
   740 
   741 	// determine size of area
   741 	/* determine size of area */
   742 	{
   742 	{
   743 		Point pt = RemapCoords(x, y, 241);
   743 		Point pt = RemapCoords(x, y, 241);
   744 		width = (vd->dpi.left + vd->dpi.width - pt.x + 95) >> 6;
   744 		width = (vd->dpi.left + vd->dpi.width - pt.x + 95) >> 6;
   745 		height = (vd->dpi.top + vd->dpi.height - pt.y) >> 5 << 1;
   745 		height = (vd->dpi.top + vd->dpi.height - pt.y) >> 5 << 1;
   746 	}
   746 	}
  1126 							)) {
  1126 							)) {
  1127 						continue;
  1127 						continue;
  1128 					}
  1128 					}
  1129 				}
  1129 				}
  1130 
  1130 
  1131 				// Swap the two sprites ps and ps2 using bubble-sort algorithm.
  1131 				/* Swap the two sprites ps and ps2 using bubble-sort algorithm. */
  1132 				psd3 = psd;
  1132 				psd3 = psd;
  1133 				do {
  1133 				do {
  1134 					ParentSpriteToDraw* temp = *psd3;
  1134 					ParentSpriteToDraw* temp = *psd3;
  1135 					*psd3 = ps2;
  1135 					*psd3 = ps2;
  1136 					ps2 = temp;
  1136 					ps2 = temp;
  1271 	ViewportAddTownNames(&vd.dpi);
  1271 	ViewportAddTownNames(&vd.dpi);
  1272 	ViewportAddStationNames(&vd.dpi);
  1272 	ViewportAddStationNames(&vd.dpi);
  1273 	ViewportAddSigns(&vd.dpi);
  1273 	ViewportAddSigns(&vd.dpi);
  1274 	ViewportAddWaypoints(&vd.dpi);
  1274 	ViewportAddWaypoints(&vd.dpi);
  1275 
  1275 
  1276 	// This assert should never happen (because the length of the parent_list
  1276 	/* This assert should never happen (because the length of the parent_list
  1277 	//  is checked)
  1277 	 *  is checked) */
  1278 	assert(vd.parent_list <= endof(parent_list));
  1278 	assert(vd.parent_list <= endof(parent_list));
  1279 
  1279 
  1280 	if (vd.first_tile != NULL) ViewportDrawTileSprites(vd.first_tile);
  1280 	if (vd.first_tile != NULL) ViewportDrawTileSprites(vd.first_tile);
  1281 
  1281 
  1282 	/* null terminate parent sprite list */
  1282 	/* null terminate parent sprite list */
  1288 	if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string);
  1288 	if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string);
  1289 
  1289 
  1290 	_cur_dpi = old_dpi;
  1290 	_cur_dpi = old_dpi;
  1291 }
  1291 }
  1292 
  1292 
  1293 // Make sure we don't draw a too big area at a time.
  1293 /** Make sure we don't draw a too big area at a time.
  1294 // If we do, the sprite memory will overflow.
  1294  * If we do, the sprite memory will overflow. */
  1295 static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom)
  1295 static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom)
  1296 {
  1296 {
  1297 	if (((bottom - top) * (right - left) << (2 * vp->zoom)) > 180000) {
  1297 	if (((bottom - top) * (right - left) << (2 * vp->zoom)) > 180000) {
  1298 		if ((bottom - top) > (right - left)) {
  1298 		if ((bottom - top) > (right - left)) {
  1299 			int t = (top + bottom) >> 1;
  1299 			int t = (top + bottom) >> 1;
  1357 		int x;
  1357 		int x;
  1358 		int y;
  1358 		int y;
  1359 		int vx;
  1359 		int vx;
  1360 		int vy;
  1360 		int vy;
  1361 
  1361 
  1362 		// Center of the viewport is hot spot
  1362 		/* Center of the viewport is hot spot */
  1363 		x = WP(w,vp_d).scrollpos_x + vp->virtual_width / 2;
  1363 		x = WP(w,vp_d).scrollpos_x + vp->virtual_width / 2;
  1364 		y = WP(w,vp_d).scrollpos_y + vp->virtual_height / 2;
  1364 		y = WP(w,vp_d).scrollpos_y + vp->virtual_height / 2;
  1365 		// Convert viewport coordinates to map coordinates
  1365 		/* Convert viewport coordinates to map coordinates
  1366 		// Calculation is scaled by 4 to avoid rounding errors
  1366 		 * Calculation is scaled by 4 to avoid rounding errors */
  1367 		vx = -x + y * 2;
  1367 		vx = -x + y * 2;
  1368 		vy =  x + y * 2;
  1368 		vy =  x + y * 2;
  1369 		// clamp to size of map
  1369 		/* clamp to size of map */
  1370 		vx = clamp(vx, 0 * 4, MapMaxX() * TILE_SIZE * 4);
  1370 		vx = clamp(vx, 0 * 4, MapMaxX() * TILE_SIZE * 4);
  1371 		vy = clamp(vy, 0 * 4, MapMaxY() * TILE_SIZE * 4);
  1371 		vy = clamp(vy, 0 * 4, MapMaxY() * TILE_SIZE * 4);
  1372 		// Convert map coordinates to viewport coordinates
  1372 		/* Convert map coordinates to viewport coordinates */
  1373 		x = (-vx + vy) / 2;
  1373 		x = (-vx + vy) / 2;
  1374 		y = ( vx + vy) / 4;
  1374 		y = ( vx + vy) / 4;
  1375 		// Set position
  1375 		/* Set position */
  1376 		WP(w, vp_d).scrollpos_x = x - vp->virtual_width / 2;
  1376 		WP(w, vp_d).scrollpos_x = x - vp->virtual_width / 2;
  1377 		WP(w, vp_d).scrollpos_y = y - vp->virtual_height / 2;
  1377 		WP(w, vp_d).scrollpos_y = y - vp->virtual_height / 2;
  1378 
  1378 
  1379 		SetViewportPosition(w, WP(w, vp_d).scrollpos_x, WP(w, vp_d).scrollpos_y);
  1379 		SetViewportPosition(w, WP(w, vp_d).scrollpos_x, WP(w, vp_d).scrollpos_y);
  1380 	}
  1380 	}
  1857 	_thd.offs.y = oy * TILE_SIZE;
  1857 	_thd.offs.y = oy * TILE_SIZE;
  1858 	_thd.new_outersize.x = sx * TILE_SIZE;
  1858 	_thd.new_outersize.x = sx * TILE_SIZE;
  1859 	_thd.new_outersize.y = sy * TILE_SIZE;
  1859 	_thd.new_outersize.y = sy * TILE_SIZE;
  1860 }
  1860 }
  1861 
  1861 
  1862 /* returns the best autorail highlight type from map coordinates */
  1862 /** returns the best autorail highlight type from map coordinates */
  1863 static byte GetAutorailHT(int x, int y)
  1863 static byte GetAutorailHT(int x, int y)
  1864 {
  1864 {
  1865 	return HT_RAIL | _AutorailPiece[x & 0xF][y & 0xF];
  1865 	return HT_RAIL | _AutorailPiece[x & 0xF][y & 0xF];
  1866 }
  1866 }
  1867 
  1867 
  1868 // called regular to update tile highlighting in all cases
  1868 /** called regular to update tile highlighting in all cases */
  1869 void UpdateTileSelection()
  1869 void UpdateTileSelection()
  1870 {
  1870 {
  1871 	int x1;
  1871 	int x1;
  1872 	int y1;
  1872 	int y1;
  1873 
  1873 
  1910 			_thd.new_pos.x = x1 & ~0xF;
  1910 			_thd.new_pos.x = x1 & ~0xF;
  1911 			_thd.new_pos.y = y1 & ~0xF;
  1911 			_thd.new_pos.y = y1 & ~0xF;
  1912 		}
  1912 		}
  1913 	}
  1913 	}
  1914 
  1914 
  1915 	// redraw selection
  1915 	/* redraw selection */
  1916 	if (_thd.drawstyle != _thd.new_drawstyle ||
  1916 	if (_thd.drawstyle != _thd.new_drawstyle ||
  1917 			_thd.pos.x != _thd.new_pos.x || _thd.pos.y != _thd.new_pos.y ||
  1917 			_thd.pos.x != _thd.new_pos.x || _thd.pos.y != _thd.new_pos.y ||
  1918 			_thd.size.x != _thd.new_size.x || _thd.size.y != _thd.new_size.y ||
  1918 			_thd.size.x != _thd.new_size.x || _thd.size.y != _thd.new_size.y ||
  1919 	    _thd.outersize.x != _thd.new_outersize.x ||
  1919 	    _thd.outersize.x != _thd.new_outersize.x ||
  1920 	    _thd.outersize.y != _thd.new_outersize.y) {
  1920 	    _thd.outersize.y != _thd.new_outersize.y) {
  1921 		// clear the old selection?
  1921 		/* clear the old selection? */
  1922 		if (_thd.drawstyle) SetSelectionTilesDirty();
  1922 		if (_thd.drawstyle) SetSelectionTilesDirty();
  1923 
  1923 
  1924 		_thd.drawstyle = _thd.new_drawstyle;
  1924 		_thd.drawstyle = _thd.new_drawstyle;
  1925 		_thd.pos = _thd.new_pos;
  1925 		_thd.pos = _thd.new_pos;
  1926 		_thd.size = _thd.new_size;
  1926 		_thd.size = _thd.new_size;
  1927 		_thd.outersize = _thd.new_outersize;
  1927 		_thd.outersize = _thd.new_outersize;
  1928 		_thd.dirty = 0xff;
  1928 		_thd.dirty = 0xff;
  1929 
  1929 
  1930 		// draw the new selection?
  1930 		/* draw the new selection? */
  1931 		if (_thd.new_drawstyle) SetSelectionTilesDirty();
  1931 		if (_thd.new_drawstyle) SetSelectionTilesDirty();
  1932 	}
  1932 	}
  1933 }
  1933 }
  1934 
  1934 
  1935 // highlighting tiles while only going over them with the mouse
  1935 /** highlighting tiles while only going over them with the mouse */
  1936 void VpStartPlaceSizing(TileIndex tile, int user)
  1936 void VpStartPlaceSizing(TileIndex tile, int user)
  1937 {
  1937 {
  1938 	_thd.userdata = user;
  1938 	_thd.userdata = user;
  1939 	_thd.selend.x = TileX(tile) * TILE_SIZE;
  1939 	_thd.selend.x = TileX(tile) * TILE_SIZE;
  1940 	_thd.selstart.x = TileX(tile) * TILE_SIZE;
  1940 	_thd.selstart.x = TileX(tile) * TILE_SIZE;
  1980 {
  1980 {
  1981 	_thd.selend.x = -1;
  1981 	_thd.selend.x = -1;
  1982 	_special_mouse_mode = WSM_PRESIZE;
  1982 	_special_mouse_mode = WSM_PRESIZE;
  1983 }
  1983 }
  1984 
  1984 
  1985 /* returns information about the 2x1 piece to be build.
  1985 /** returns information about the 2x1 piece to be build.
  1986  * The lower bits (0-3) are the track type. */
  1986  * The lower bits (0-3) are the track type. */
  1987 static byte Check2x1AutoRail(int mode)
  1987 static byte Check2x1AutoRail(int mode)
  1988 {
  1988 {
  1989 	int fxpy = _tile_fract_coords.x + _tile_fract_coords.y;
  1989 	int fxpy = _tile_fract_coords.x + _tile_fract_coords.y;
  1990 	int sxpy = (_thd.selend.x & 0xF) + (_thd.selend.y & 0xF);
  1990 	int sxpy = (_thd.selend.x & 0xF) + (_thd.selend.y & 0xF);
  2131 	return (int)(h1 - h0) * 50;
  2131 	return (int)(h1 - h0) * 50;
  2132 }
  2132 }
  2133 
  2133 
  2134 static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
  2134 static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
  2135 
  2135 
  2136 // while dragging
  2136 /** while dragging */
  2137 static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y, int method)
  2137 static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y, int method)
  2138 {
  2138 {
  2139 	HighLightStyle b;
  2139 	HighLightStyle b;
  2140 	uint w, h;
  2140 	uint w, h;
  2141 
  2141 
  2382 
  2382 
  2383 	_thd.selend.x = x;
  2383 	_thd.selend.x = x;
  2384 	_thd.selend.y = y;
  2384 	_thd.selend.y = y;
  2385 }
  2385 }
  2386 
  2386 
  2387 // while dragging
  2387 /** while dragging */
  2388 bool VpHandlePlaceSizingDrag()
  2388 bool VpHandlePlaceSizingDrag()
  2389 {
  2389 {
  2390 	Window *w;
  2390 	Window *w;
  2391 	WindowEvent e;
  2391 	WindowEvent e;
  2392 
  2392 
  2393 	if (_special_mouse_mode != WSM_SIZING) return true;
  2393 	if (_special_mouse_mode != WSM_SIZING) return true;
  2394 
  2394 
  2395 	e.we.place.userdata = _thd.userdata;
  2395 	e.we.place.userdata = _thd.userdata;
  2396 
  2396 
  2397 	// stop drag mode if the window has been closed
  2397 	/* stop drag mode if the window has been closed */
  2398 	w = FindWindowById(_thd.window_class,_thd.window_number);
  2398 	w = FindWindowById(_thd.window_class,_thd.window_number);
  2399 	if (w == NULL) {
  2399 	if (w == NULL) {
  2400 		ResetObjectToPlace();
  2400 		ResetObjectToPlace();
  2401 		return false;
  2401 		return false;
  2402 	}
  2402 	}
  2403 
  2403 
  2404 	// while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() )
  2404 	/* while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() ) */
  2405 	if (_left_button_down) {
  2405 	if (_left_button_down) {
  2406 		e.event = WE_PLACE_DRAG;
  2406 		e.event = WE_PLACE_DRAG;
  2407 		e.we.place.pt = GetTileBelowCursor();
  2407 		e.we.place.pt = GetTileBelowCursor();
  2408 		w->wndproc(w, &e);
  2408 		w->wndproc(w, &e);
  2409 		return false;
  2409 		return false;
  2410 	}
  2410 	}
  2411 
  2411 
  2412 	// mouse button released..
  2412 	/* mouse button released..
  2413 	// keep the selected tool, but reset it to the original mode.
  2413 	 * keep the selected tool, but reset it to the original mode. */
  2414 	_special_mouse_mode = WSM_NONE;
  2414 	_special_mouse_mode = WSM_NONE;
  2415 	if (_thd.next_drawstyle == HT_RECT) {
  2415 	if (_thd.next_drawstyle == HT_RECT) {
  2416 		_thd.place_mode = VHM_RECT;
  2416 		_thd.place_mode = VHM_RECT;
  2417 	} else if ((e.we.place.userdata & 0xF) == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik
  2417 	} else if ((e.we.place.userdata & 0xF) == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik
  2418 		_thd.place_mode = VHM_RECT;
  2418 		_thd.place_mode = VHM_RECT;
  2423 	} else {
  2423 	} else {
  2424 		_thd.place_mode = VHM_POINT;
  2424 		_thd.place_mode = VHM_POINT;
  2425 	}
  2425 	}
  2426 	SetTileSelectSize(1, 1);
  2426 	SetTileSelectSize(1, 1);
  2427 
  2427 
  2428 	// and call the mouseup event.
  2428 	/* and call the mouseup event. */
  2429 	e.event = WE_PLACE_MOUSEUP;
  2429 	e.event = WE_PLACE_MOUSEUP;
  2430 	e.we.place.pt = _thd.selend;
  2430 	e.we.place.pt = _thd.selend;
  2431 	e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y);
  2431 	e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y);
  2432 	e.we.place.starttile = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
  2432 	e.we.place.starttile = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
  2433 	w->wndproc(w, &e);
  2433 	w->wndproc(w, &e);
  2444 
  2444 
  2445 void SetObjectToPlace(CursorID icon, SpriteID pal, byte mode, WindowClass window_class, WindowNumber window_num)
  2445 void SetObjectToPlace(CursorID icon, SpriteID pal, byte mode, WindowClass window_class, WindowNumber window_num)
  2446 {
  2446 {
  2447 	Window *w;
  2447 	Window *w;
  2448 
  2448 
  2449 	// undo clicking on button
  2449 	/* undo clicking on button */
  2450 	if (_thd.place_mode != 0) {
  2450 	if (_thd.place_mode != 0) {
  2451 		_thd.place_mode = 0;
  2451 		_thd.place_mode = 0;
  2452 		w = FindWindowById(_thd.window_class, _thd.window_number);
  2452 		w = FindWindowById(_thd.window_class, _thd.window_number);
  2453 		if (w != NULL) CallWindowEventNP(w, WE_ABORT_PLACE_OBJ);
  2453 		if (w != NULL) CallWindowEventNP(w, WE_ABORT_PLACE_OBJ);
  2454 	}
  2454 	}