viewport.c
changeset 1070 bd31ed783fd3
parent 988 4304525d1b8b
child 1083 8e64dc3ed29f
equal deleted inserted replaced
1069:f6b7607231e5 1070:bd31ed783fd3
   593 
   593 
   594 #endif
   594 #endif
   595 
   595 
   596 static void DrawSelectionSprite(uint32 image, const TileInfo *ti)
   596 static void DrawSelectionSprite(uint32 image, const TileInfo *ti)
   597 {
   597 {
   598 	if (_added_tile_sprite) {
   598 	AddSortableSpriteToDraw(image, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7);
   599 		DrawGroundSpriteAt(image, ti->x, ti->y, ti->z + 7);
       
   600 	} else {
       
   601 		AddSortableSpriteToDraw(image, ti->x, ti->y, 0x10, 0x10, 1, ti->z + 7);
       
   602 	}
       
   603 }
   599 }
   604 
   600 
   605 static bool IsPartOfAutoLine(int px, int py)
   601 static bool IsPartOfAutoLine(int px, int py)
   606 {
   602 {
   607 	const TileHighlightData *thd = _thd_ptr;
   603 	const TileHighlightData *thd = _thd_ptr;
   608 
   604 
   609 	px -= thd->selstart.x;
   605 	px -= thd->selstart.x;
   610 	py -= thd->selstart.y;
   606 	py -= thd->selstart.y;
   611 
   607 
   612 	switch(thd->drawstyle) {
   608 	switch(thd->drawstyle) {
   613 	case HT_LINE | 0: return px == py || px == py + 16;
   609 	case HT_LINE | HT_DIR_X:  return py == 0; // x direction
   614 	case HT_LINE | 1: return px == py || px == py - 16;
   610 	case HT_LINE | HT_DIR_Y:  return px == 0; // y direction
   615 	case HT_LINE | 2: return px == -py || px == -py + 16;
   611 	case HT_LINE | HT_DIR_HU: return px == -py || px == -py - 16; // horizontal upper
   616 	case HT_LINE | 3: return px == -py || px == -py - 16;
   612 	case HT_LINE | HT_DIR_HL: return px == -py || px == -py + 16; // horizontal lower
       
   613 	case HT_LINE | HT_DIR_VL: return px == py || px == py + 16; // vertival left
       
   614 	case HT_LINE | HT_DIR_VR: return px == py || px == py - 16; // vertical right
   617 	default:
   615 	default:
   618 		NOT_REACHED();
   616 		NOT_REACHED();
   619 	}
   617 	}
   620 
   618 
   621 	/* useless, but avoids compiler warning this way */
   619 	/* useless, but avoids compiler warning this way */
   622 	return 0;
   620 	return 0;
   623 }
   621 }
       
   622 
       
   623 // [direction][side]
       
   624 static const int AutorailType[6][2] = {
       
   625 	{ HT_DIR_X,  HT_DIR_X },
       
   626 	{ HT_DIR_Y,  HT_DIR_Y },
       
   627 	{ HT_DIR_HU, HT_DIR_HL },
       
   628 	{ HT_DIR_HL, HT_DIR_HU },
       
   629 	{ HT_DIR_VL, HT_DIR_VR },
       
   630 	{ HT_DIR_VR, HT_DIR_VL }
       
   631 };
       
   632 
       
   633 #include "table/autorail.h"
   624 
   634 
   625 static void DrawTileSelection(const TileInfo *ti)
   635 static void DrawTileSelection(const TileInfo *ti)
   626 {
   636 {
   627 	uint32 image;
   637 	uint32 image;
   628 	const TileHighlightData *thd = _thd_ptr;
   638 	const TileHighlightData *thd = _thd_ptr;
   655 				if (!(ti->tileh & 2) && (ti->tileh & 0x10)) {
   665 				if (!(ti->tileh & 2) && (ti->tileh & 0x10)) {
   656 					z += 8;
   666 					z += 8;
   657 				}
   667 				}
   658 			}
   668 			}
   659 			DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? 0x306 : 0xFEE,ti->x, ti->y, z);
   669 			DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? 0x306 : 0xFEE,ti->x, ti->y, z);
   660 		} else {
   670 
   661 			if (IsPartOfAutoLine(ti->x, ti->y)) {
   671 		} else if (thd->drawstyle & HT_RAIL /*&& thd->place_mode == VHM_RAIL*/) { // autorail highlight piece under cursor
   662 				image = 0x2F0 + _tileh_to_sprite[ti->tileh];
   672 			int type = thd->drawstyle & 0xF;
       
   673 			assert(type<=5);
       
   674 			image = SPR_AUTORAIL_BASE + AutorailTilehSprite[ ti->tileh ][ AutorailType[type][0] ];
       
   675 
       
   676 			if (thd->make_square_red) image |= 0x3048000;
       
   677 			DrawSelectionSprite(image, ti);
       
   678 
       
   679 		} else if (IsPartOfAutoLine(ti->x, ti->y)) { // autorail highlighting long line
       
   680 				int dir = thd->drawstyle & ~0xF0;
       
   681 				uint start = TILE_FROM_XY(thd->selstart.x, thd->selstart.y);
       
   682 				int diffx, diffy;
       
   683 				int side;
       
   684 
       
   685 				diffx = myabs(TileX(start)-TileX(ti->tile));
       
   686 				diffy = myabs(TileY(start)-TileY(ti->tile));
       
   687 				
       
   688 				side = myabs( diffx-diffy );
       
   689 				if(dir<2) side = 0;
       
   690 
       
   691 				image = SPR_AUTORAIL_BASE + AutorailTilehSprite[ ti->tileh ][ AutorailType[dir][side] ];
       
   692 
   663 				if (thd->make_square_red) image |= 0x3048000;
   693 				if (thd->make_square_red) image |= 0x3048000;
   664 				DrawSelectionSprite(image, ti);
   694 				DrawSelectionSprite(image, ti);
   665 			}
   695 			} 
   666 		}
       
   667 		return;
   696 		return;
   668 	}
   697 	}
   669 
   698 
   670 	// Check if it's inside the outer area?
   699 	// Check if it's inside the outer area?
   671 	if (thd->outersize.x &&
   700 	if (thd->outersize.x &&
  1713 
  1742 
  1714 	pt = GetTileBelowCursor();
  1743 	pt = GetTileBelowCursor();
  1715 	if (pt.x == -1)
  1744 	if (pt.x == -1)
  1716 		return;
  1745 		return;
  1717 
  1746 
  1718 	if (_thd.place_mode == 2) {
  1747 	if (_thd.place_mode == VHM_POINT) {
  1719 		pt.x += 8;
  1748 		pt.x += 8;
  1720 		pt.y += 8;
  1749 		pt.y += 8;
  1721 	}
  1750 	}
  1722 
  1751 
  1723 	_tile_fract_coords.x = pt.x & 0xF;
  1752 	_tile_fract_coords.x = pt.x & 0xF;
  1808 	thd->offs.y = oy * 16;
  1837 	thd->offs.y = oy * 16;
  1809 	thd->new_outersize.x = sx * 16;
  1838 	thd->new_outersize.x = sx * 16;
  1810 	thd->new_outersize.y = sy * 16;
  1839 	thd->new_outersize.y = sy * 16;
  1811 }
  1840 }
  1812 
  1841 
  1813 
  1842 /* returns the best autorail highlight type from map coordinates */
       
  1843 static byte GetAutorailHT(int x, int y)
       
  1844 {
       
  1845 	int i;
       
  1846 	i = AutorailPiece[x&0xF][y&0xF];
       
  1847 	return HT_RAIL | i;
       
  1848 }
       
  1849 
       
  1850 // called regular to update tile highlighting in all cases
  1814 void UpdateTileSelection()
  1851 void UpdateTileSelection()
  1815 {
  1852 {
  1816 	TileHighlightData *thd = _thd_ptr;
  1853 	TileHighlightData *thd = _thd_ptr;
  1817 	Point pt;
  1854 	Point pt;
  1818 	int x1,y1;
  1855 	int x1,y1;
  1819 
  1856 
  1820 	thd->new_drawstyle = 0;
  1857 	thd->new_drawstyle = 0;
  1821 
  1858 
  1822 	if (thd->place_mode == 3) {
  1859 	if (thd->place_mode == VHM_SPECIAL) {
  1823 		x1 = thd->selend.x;
  1860 		x1 = thd->selend.x;
  1824 		y1 = thd->selend.y;
  1861 		y1 = thd->selend.y;
  1825 		if (x1 != -1) {
  1862 		if (x1 != -1) {
  1826 			int x2 = thd->selstart.x;
  1863 			int x2 = thd->selstart.x;
  1827 			int y2 = thd->selstart.y;
  1864 			int y2 = thd->selstart.y;
  1834 			thd->new_pos.y = y1;
  1871 			thd->new_pos.y = y1;
  1835 			thd->new_size.x = x2 - x1 + 16;
  1872 			thd->new_size.x = x2 - x1 + 16;
  1836 			thd->new_size.y = y2 - y1 + 16;
  1873 			thd->new_size.y = y2 - y1 + 16;
  1837 			thd->new_drawstyle = thd->next_drawstyle;
  1874 			thd->new_drawstyle = thd->next_drawstyle;
  1838 		}
  1875 		}
  1839 	} else if (thd->place_mode != 0) {
  1876 	} else if (thd->place_mode != VHM_NONE) {
  1840 		pt = GetTileBelowCursor();
  1877 		pt = GetTileBelowCursor();
  1841 		x1 = pt.x;
  1878 		x1 = pt.x;
  1842 		y1 = pt.y;
  1879 		y1 = pt.y;
  1843 		if (x1 != -1) {
  1880 		if (x1 != -1) {
  1844 			if (thd->place_mode == 1) {
  1881 			switch (thd->place_mode) {
  1845 				thd->new_drawstyle = HT_RECT;
  1882 				case VHM_RECT:
  1846 			} else {
  1883 					thd->new_drawstyle = HT_RECT;
  1847 				thd->new_drawstyle = HT_POINT;
  1884 					break;
  1848 				x1 += 8;
  1885 				case VHM_POINT:
  1849 				y1 += 8;
  1886 					thd->new_drawstyle = HT_POINT;
       
  1887 					x1 += 8;
       
  1888 					y1 += 8;
       
  1889 					break;
       
  1890 				case VHM_RAIL:
       
  1891 					thd->new_drawstyle = GetAutorailHT(pt.x, pt.y); // draw one highlighted tile
  1850 			}
  1892 			}
  1851 			thd->new_pos.x = x1 & ~0xF;
  1893 			thd->new_pos.x = x1 & ~0xF;
  1852 			thd->new_pos.y = y1 & ~0xF;
  1894 			thd->new_pos.y = y1 & ~0xF;
  1853 		}
  1895 		}
  1854 	}
  1896 	}
  1855 
  1897 
       
  1898 	// redraw selection
  1856 	if (thd->drawstyle != thd->new_drawstyle ||
  1899 	if (thd->drawstyle != thd->new_drawstyle ||
  1857 			thd->pos.x != thd->new_pos.x || thd->pos.y != thd->new_pos.y ||
  1900 			thd->pos.x != thd->new_pos.x || thd->pos.y != thd->new_pos.y ||
  1858 			thd->size.x != thd->new_size.x || thd->size.y != thd->new_size.y) {
  1901 			thd->size.x != thd->new_size.x || thd->size.y != thd->new_size.y) {
  1859 
  1902 
  1860 		// clear the old selection?
  1903 		// clear the old selection?
  1869 		// draw the new selection?
  1912 		// draw the new selection?
  1870 		if (thd->new_drawstyle) SetSelectionTilesDirty();
  1913 		if (thd->new_drawstyle) SetSelectionTilesDirty();
  1871 	}
  1914 	}
  1872 }
  1915 }
  1873 
  1916 
       
  1917 // highlighting tiles while only going over them with the mouse
  1874 void VpStartPlaceSizing(uint tile, int user)
  1918 void VpStartPlaceSizing(uint tile, int user)
  1875 {
  1919 {
  1876 	TileHighlightData *thd;
  1920 	TileHighlightData *thd;
  1877 
       
  1878 	thd = _thd_ptr;
  1921 	thd = _thd_ptr;
  1879 	thd->userdata = user;
  1922 	thd->userdata = user;
  1880 	thd->selend.x = TileX(tile) * 16;
  1923 	thd->selend.x = TileX(tile) * 16;
  1881 	thd->selstart.x = TileX(tile) * 16;
  1924 	thd->selstart.x = TileX(tile) * 16;
  1882 	thd->selend.y = TileY(tile) * 16;
  1925 	thd->selend.y = TileY(tile) * 16;
  1883 	thd->selstart.y = TileY(tile) * 16;
  1926 	thd->selstart.y = TileY(tile) * 16;
  1884 	if (thd->place_mode == 1) {
  1927 	if (thd->place_mode == VHM_RECT) {
  1885 		thd->place_mode = 3;
  1928 		thd->place_mode = VHM_SPECIAL;
  1886 		thd->next_drawstyle = HT_RECT;
  1929 		thd->next_drawstyle = HT_RECT;
       
  1930 	} else if (thd->place_mode == VHM_RAIL) { // autorail one piece
       
  1931 		thd->place_mode = VHM_SPECIAL;
       
  1932 		thd->next_drawstyle = thd->drawstyle;
  1887 	} else {
  1933 	} else {
  1888 		thd->place_mode = 3;
  1934 		thd->place_mode = VHM_SPECIAL;
  1889 		thd->next_drawstyle = HT_POINT;
  1935 		thd->next_drawstyle = HT_POINT;
  1890 	}
  1936 	}
  1891 	_special_mouse_mode = WSM_SIZING;
  1937 	_special_mouse_mode = WSM_SIZING;
  1892 }
  1938 }
  1893 
  1939 
  1910 {
  1956 {
  1911 	_thd.selend.x = -1;
  1957 	_thd.selend.x = -1;
  1912 	_special_mouse_mode = WSM_PRESIZE;
  1958 	_special_mouse_mode = WSM_PRESIZE;
  1913 }
  1959 }
  1914 
  1960 
  1915 static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y)
  1961 /* returns information about the 2x1 piece to be build. 
       
  1962  * The lower bits (0-3) are the track type. */
       
  1963 static byte Check2x1AutoRail(int mode)
       
  1964 {
       
  1965 	TileHighlightData *thd = &_thd;
       
  1966 	int fxpy = _tile_fract_coords.x + _tile_fract_coords.y;
       
  1967 	int sxpy = (thd->selend.x & 0xF) + (thd->selend.y & 0xF);
       
  1968 	int fxmy = _tile_fract_coords.x - _tile_fract_coords.y;
       
  1969 	int sxmy = (thd->selend.x & 0xF) - (thd->selend.y & 0xF);
       
  1970 
       
  1971 	switch(mode) {
       
  1972 	case 0: // end piece is lower right
       
  1973 		if (fxpy >= 20 && sxpy <= 12) { /*SwapSelection(); DoRailroadTrack(0); */return 3; }
       
  1974 		if (fxmy < -3 && sxmy > 3) {/* DoRailroadTrack(0); */return 5; }
       
  1975 		return 1;
       
  1976 		break;
       
  1977 
       
  1978 	case 1:
       
  1979 		if (fxmy > 3 && sxmy < -3) { /*SwapSelection(); DoRailroadTrack(0); */return 4; }
       
  1980 		if (fxpy <= 12 && sxpy >= 20) { /*DoRailroadTrack(0); */return 2; }
       
  1981 		return 1;
       
  1982 		break;
       
  1983 
       
  1984 	case 2:
       
  1985 		if (fxmy > 3 && sxmy < -3) { /*DoRailroadTrack(3);*/ return 4; }
       
  1986 		if (fxpy >= 20 && sxpy <= 12) { /*SwapSelection(); DoRailroadTrack(0); */return 3; }
       
  1987 		return 0;
       
  1988 		break;
       
  1989 
       
  1990 	case 3:
       
  1991 		if (fxmy < -3 && sxmy > 3) { /*SwapSelection(); DoRailroadTrack(3);*/ return 5; }
       
  1992 		if (fxpy <= 12 && sxpy >= 20) { /*DoRailroadTrack(0); */return 2; }
       
  1993 		return 0;
       
  1994 		break;
       
  1995 	}
       
  1996 
       
  1997 	return 0; // avoids compiler warnings
       
  1998 }
       
  1999 
       
  2000 
       
  2001 // while dragging
       
  2002 static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y, int method)
  1916 {
  2003 {
  1917 	int d;
  2004 	int d;
  1918 	bool b;
  2005 	byte b=6;
  1919 	uint w,h;
  2006 	uint w,h;
  1920 
  2007 
  1921 	w =	myabs((x & ~0xF) - thd->selstart.x) + 16;
  2008 	int dx = thd->selstart.x - (thd->selend.x&~0xF);
  1922 	h = myabs((y & ~0xF) - thd->selstart.y) + 16;
  2009 	int dy = thd->selstart.y - (thd->selend.y&~0xF);
  1923 
  2010 	w = myabs(dx) + 16;
  1924 	// vertical and horizontal lines are really simple
  2011 	h = myabs(dy) + 16;
  1925 	if (w == 16 || h == 16) {
  2012 
  1926 		b = HT_RECT;
  2013 	if (TILE_FROM_XY(thd->selstart.x, thd->selstart.y) == TILE_FROM_XY(x,y)) { // check if we're only within one tile
  1927 	} else if (w * 2 < h) { // see if we're closer to rect?
  2014 			if(method == VPM_RAILDIRS)
       
  2015 				b = GetAutorailHT(x, y);
       
  2016 			else // rect for autosignals on one tile
       
  2017 				b = HT_RECT;
       
  2018 	} else if (h == 16) { // Is this in X direction?
       
  2019 		if (dx==16) // 2x1 special handling
       
  2020 			b = (Check2x1AutoRail(3)) | HT_LINE;
       
  2021 		else if (dx==-16)
       
  2022 			b = (Check2x1AutoRail(2)) | HT_LINE;
       
  2023 		else 
       
  2024 			b = HT_LINE | HT_DIR_X;
       
  2025 		y = thd->selstart.y;
       
  2026 	} else if (w == 16) { // Or Y direction?
       
  2027 		if (dy==16) // 2x1 special handling
       
  2028 			b = (Check2x1AutoRail(1)) | HT_LINE;
       
  2029 		else if (dy==-16) // 2x1 other direction
       
  2030 			b = (Check2x1AutoRail(0)) | HT_LINE;
       
  2031 		else 
       
  2032 			b = HT_LINE | HT_DIR_Y;
  1928 		x = thd->selstart.x;
  2033 		x = thd->selstart.x;
  1929 		b = HT_RECT;
  2034 	} else if (w > h * 2) { // still count as x dir?
  1930 	} else if (w > h * 2) {
  2035 			b = HT_LINE | HT_DIR_X;
  1931 		y = thd->selstart.y;
  2036 		y = thd->selstart.y;
  1932 		b = HT_RECT;
  2037 	} else if (h > w * 2) { // still count as y dir?
  1933 	} else {
  2038 			b = HT_LINE | HT_DIR_Y;
       
  2039 		x = thd->selstart.x;
       
  2040 	} else { // complicated direction
  1934 		d = w - h;
  2041 		d = w - h;
       
  2042 		thd->selend.x = thd->selend.x&~0xF;
       
  2043 		thd->selend.y = thd->selend.y&~0xF;
  1935 
  2044 
  1936 		// four cases.
  2045 		// four cases.
  1937 		if (x > thd->selstart.x) {
  2046 		if (x > thd->selstart.x) {
  1938 			if (y > thd->selstart.y) {
  2047 			if (y > thd->selstart.y) {
  1939 				// south
  2048 				// south
  1940 				if (d ==0) b = (x & 0xF) > (y & 0xF) ? HT_LINE | 0 : HT_LINE | 1;
  2049 				if (d ==0) b = (x & 0xF) > (y & 0xF) ? HT_LINE | HT_DIR_VL : HT_LINE | HT_DIR_VR;
  1941 				else if (d >= 0) { x = thd->selstart.x + h; b = HT_LINE | 0; } // return px == py || px == py + 16;
  2050 				else if (d >= 0) { x = thd->selstart.x + h; b = HT_LINE | HT_DIR_VL; } // return px == py || px == py + 16;
  1942 				else { y = thd->selstart.y + w; b = HT_LINE | 1; } // return px == py || px == py - 16;
  2051 				else { y = thd->selstart.y + w; b = HT_LINE | HT_DIR_VR; } // return px == py || px == py - 16;
  1943 			} else {
  2052 			} else {
  1944 				// west
  2053 				// west
  1945 				if (d ==0) b = (x & 0xF) + (y & 0xF) >= 0x10 ? HT_LINE | 2 : HT_LINE | 3;
  2054 				if (d ==0) b = (x & 0xF) + (y & 0xF) >= 0x10 ? HT_LINE | HT_DIR_HL : HT_LINE | HT_DIR_HU;
  1946 				else if (d >= 0) { x = thd->selstart.x + h; b = HT_LINE | 2; }
  2055 				else if (d >= 0) { x = thd->selstart.x + h; b = HT_LINE | HT_DIR_HL; }
  1947 				else { y = thd->selstart.y - w; b = HT_LINE | 3; }
  2056 				else { y = thd->selstart.y - w; b = HT_LINE | HT_DIR_HU; }
  1948 			}
  2057 			}
  1949 		} else {
  2058 		} else {
  1950 			if (y > thd->selstart.y) {
  2059 			if (y > thd->selstart.y) {
  1951 				// east
  2060 				// east
  1952 				if (d ==0) b = (x & 0xF) + (y & 0xF) >= 0x10 ? HT_LINE | 2 : HT_LINE | 3;
  2061 				if (d ==0) b = (x & 0xF) + (y & 0xF) >= 0x10 ? HT_LINE | HT_DIR_HL : HT_LINE | HT_DIR_HU;
  1953 				else if (d >= 0) { x = thd->selstart.x - h; b = HT_LINE | 3; } // return px == -py || px == -py - 16;
  2062 				else if (d >= 0) { x = thd->selstart.x - h; b = HT_LINE | HT_DIR_HU; } // return px == -py || px == -py - 16;
  1954 				else { y = thd->selstart.y + w; b = HT_LINE | 2; } // return px == -py || px == -py + 16;
  2063 				else { y = thd->selstart.y + w; b = HT_LINE | HT_DIR_HL; } // return px == -py || px == -py + 16;
  1955 			} else {
  2064 			} else {
  1956 				// north
  2065 				// north
  1957 				if (d ==0) b = (x & 0xF) > (y & 0xF) ? HT_LINE | 0 : HT_LINE | 1;
  2066 				if (d ==0) b = (x & 0xF) > (y & 0xF) ? HT_LINE | HT_DIR_VL : HT_LINE | HT_DIR_VR;
  1958 				else if (d >= 0) { x = thd->selstart.x - h; b = HT_LINE | 1; } // return px == py || px == py - 16;
  2067 				else if (d >= 0) { x = thd->selstart.x - h; b = HT_LINE | HT_DIR_VR; } // return px == py || px == py - 16;
  1959 				else { y = thd->selstart.y - w; b = HT_LINE | 0; } //return px == py || px == py + 16;
  2068 				else { y = thd->selstart.y - w; b = HT_LINE | HT_DIR_VL; } //return px == py || px == py + 16;
  1960 			}
  2069 			}
  1961 		}
  2070 		}
  1962 	}
  2071 	}
  1963 	thd->selend.x = x;
  2072 	thd->selend.x = x;
  1964 	thd->selend.y = y;
  2073 	thd->selend.y = y;
  1965 	thd->next_drawstyle = b;
  2074 	thd->next_drawstyle = b;
  1966 }
  2075 }
  1967 
  2076 
       
  2077 // while dragging
  1968 void VpSelectTilesWithMethod(int x, int y, int method)
  2078 void VpSelectTilesWithMethod(int x, int y, int method)
  1969 {
  2079 {
  1970 	TileHighlightData *thd = _thd_ptr;
  2080 	TileHighlightData *thd = _thd_ptr;
  1971 	int sx,sy;
  2081 	int sx,sy;
  1972 
       
  1973 	if (x == -1) {
  2082 	if (x == -1) {
  1974 		thd->selend.x = -1;
  2083 		thd->selend.x = -1;
  1975 		return;
  2084 		return;
  1976 	}
  2085 	}
  1977 
  2086 
  1978 	// allow drag in any rail direction
  2087 	// allow drag in any rail direction
  1979 	if (method == VPM_RAILDIRS || method == VPM_SIGNALDIRS) {
  2088 	if (method == VPM_RAILDIRS || method == VPM_SIGNALDIRS) {
  1980 		CalcRaildirsDrawstyle(thd, x, y);
  2089 		thd->selend.x = x;
       
  2090 		thd->selend.y = y;
       
  2091 		CalcRaildirsDrawstyle(thd, x, y, method);
  1981 		return;
  2092 		return;
  1982 	}
  2093 	}
  1983 
  2094 
  1984 	if (_thd.next_drawstyle == HT_POINT) { x += 8; y += 8; }
  2095 	if (_thd.next_drawstyle == HT_POINT) { x += 8; y += 8; }
  1985 
       
  1986 	//thd->next_drawstyle = HT_RECT;
       
  1987 
  2096 
  1988 	sx = thd->selstart.x;
  2097 	sx = thd->selstart.x;
  1989 	sy = thd->selstart.y;
  2098 	sy = thd->selstart.y;
  1990 
  2099 
  1991 	switch(method) {
  2100 	switch(method) {
  2015 
  2124 
  2016 	thd->selend.x = x;
  2125 	thd->selend.x = x;
  2017 	thd->selend.y = y;
  2126 	thd->selend.y = y;
  2018 }
  2127 }
  2019 
  2128 
       
  2129 // while dragging 
  2020 bool VpHandlePlaceSizingDrag()
  2130 bool VpHandlePlaceSizingDrag()
  2021 {
  2131 {
  2022 	Window *w;
  2132 	Window *w;
  2023 	WindowEvent e;
  2133 	WindowEvent e;
  2024 
  2134 
  2025 	if (_special_mouse_mode != WSM_SIZING)
  2135 	if (_special_mouse_mode != WSM_SIZING)
  2026 		return true;
  2136 		return true;
  2027 
  2137 
  2028 	e.place.userdata = _thd.userdata;
  2138 	e.place.userdata = _thd.userdata;
  2029 
  2139 
       
  2140 	// stop drag mode if the window has been closed
  2030 	w = FindWindowById(_thd.window_class,_thd.window_number);
  2141 	w = FindWindowById(_thd.window_class,_thd.window_number);
  2031 	if (w == NULL) {
  2142 	if (w == NULL) {
  2032 		ResetObjectToPlace();
  2143 		ResetObjectToPlace();
  2033 		return false;
  2144 		return false;
  2034 	}
  2145 	}
  2035 
  2146 
  2036 	// while dragging...
  2147 	// while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() )
  2037 	if (_left_button_down) {
  2148 	if (_left_button_down) {
  2038 		e.event = WE_PLACE_DRAG;
  2149 		e.event = WE_PLACE_DRAG;
  2039 		e.place.pt = GetTileBelowCursor();
  2150 		e.place.pt = GetTileBelowCursor();
  2040 		w->wndproc(w, &e);
  2151 		w->wndproc(w, &e);
  2041 		return false;
  2152 		return false;
  2042 	}
  2153 	}
  2043 
  2154 
  2044 	// mouse button released..
  2155 	// mouse button released..
  2045 	// keep the selected tool, but reset it to the original mode.
  2156 	// keep the selected tool, but reset it to the original mode.
  2046 	_special_mouse_mode = WSM_NONE;
  2157 	_special_mouse_mode = WSM_NONE;
  2047 	_thd.place_mode = (_thd.next_drawstyle == HT_RECT || _thd.next_drawstyle & HT_LINE) ? 1 : 2;
  2158 	if (_thd.next_drawstyle == HT_RECT) 
  2048 
  2159 		_thd.place_mode = VHM_RECT;
       
  2160 	else if ((e.place.userdata & 0xF) == VPM_SIGNALDIRS) // some might call this a hack... -- Dominik
       
  2161 		_thd.place_mode = VHM_RECT;
       
  2162 	else if (_thd.next_drawstyle & HT_LINE)
       
  2163 		_thd.place_mode = VHM_RAIL;
       
  2164 	else if (_thd.next_drawstyle & HT_RAIL)
       
  2165 		_thd.place_mode = VHM_RAIL;
       
  2166 	else
       
  2167 		_thd.place_mode = VHM_POINT;
  2049 	SetTileSelectSize(1, 1);
  2168 	SetTileSelectSize(1, 1);
  2050 
  2169 
  2051 	// and call the mouseup event.
  2170 	// and call the mouseup event.
  2052 	e.event = WE_PLACE_MOUSEUP;
  2171 	e.event = WE_PLACE_MOUSEUP;
  2053 	e.place.pt = _thd.selend;
  2172 	e.place.pt = _thd.selend;
  2068 void SetObjectToPlace(int icon, byte mode, WindowClass window_class, WindowNumber window_num)
  2187 void SetObjectToPlace(int icon, byte mode, WindowClass window_class, WindowNumber window_num)
  2069 {
  2188 {
  2070 	TileHighlightData *thd = _thd_ptr;
  2189 	TileHighlightData *thd = _thd_ptr;
  2071 	Window *w;
  2190 	Window *w;
  2072 
  2191 
       
  2192 	// undo clicking on button
  2073 	if (thd->place_mode != 0) {
  2193 	if (thd->place_mode != 0) {
  2074 		thd->place_mode = 0;
  2194 		thd->place_mode = 0;
  2075 		w = FindWindowById(thd->window_class, thd->window_number);
  2195 		w = FindWindowById(thd->window_class, thd->window_number);
  2076 		if (w != NULL)
  2196 		if (w != NULL)
  2077 			CallWindowEventNP(w, WE_ABORT_PLACE_OBJ);
  2197 			CallWindowEventNP(w, WE_ABORT_PLACE_OBJ);
  2079 
  2199 
  2080 	SetTileSelectSize(1, 1);
  2200 	SetTileSelectSize(1, 1);
  2081 
  2201 
  2082 	thd->make_square_red = false;
  2202 	thd->make_square_red = false;
  2083 
  2203 
  2084 	if (mode == 4) {
  2204 	if (mode == VHM_DRAG) { // mode 4 is for dragdropping trains in the depot window
  2085 		mode = 0;
  2205 		mode = 0;
  2086 		_special_mouse_mode = WSM_DRAGDROP;
  2206 		_special_mouse_mode = WSM_DRAGDROP;
  2087 	} else {
  2207 	} else {
  2088 		_special_mouse_mode = WSM_NONE;
  2208 		_special_mouse_mode = WSM_NONE;
  2089 	}
  2209 	}
  2090 
  2210 
  2091 	thd->place_mode = mode;
  2211 	thd->place_mode = mode;
  2092 	thd->window_class = window_class;
  2212 	thd->window_class = window_class;
  2093 	thd->window_number = window_num;
  2213 	thd->window_number = window_num;
  2094 
  2214 
  2095 	if (mode == 3)
  2215 	if (mode == VHM_SPECIAL) // special tools, like tunnels or docks start with presizing mode
  2096 		VpStartPreSizing();
  2216 		VpStartPreSizing();
  2097 
  2217 
  2098 	if ( (int)icon < 0)
  2218 	if ( (int)icon < 0)
  2099 		SetAnimatedMouseCursor(_animcursors[~icon]);
  2219 		SetAnimatedMouseCursor(_animcursors[~icon]);
  2100 	else
  2220 	else