Import combined Enhanced viewport: zoom out, overlays & tooltips (r53_27127) patch

https://www.tt-forums.net/viewtopic.php?f=33&t=53394
pull/3/head
patch-import 9 years ago committed by Jonathan G Rennison
parent fd3388467f
commit 536a95dfd0

Binary file not shown.

@ -357,6 +357,7 @@
<ClCompile Include="..\src\openttd.cpp" />
<ClCompile Include="..\src\order_backup.cpp" />
<ClCompile Include="..\src\pbs.cpp" />
<ClCompile Include="..\src\plans.cpp" />
<ClCompile Include="..\src\progress.cpp" />
<ClCompile Include="..\src\rail.cpp" />
<ClCompile Include="..\src\rev.cpp" />
@ -557,6 +558,9 @@
<ClInclude Include="..\src\order_func.h" />
<ClInclude Include="..\src\order_type.h" />
<ClInclude Include="..\src\pbs.h" />
<ClInclude Include="..\src\plans_base.h" />
<ClInclude Include="..\src\plans_func.h" />
<ClInclude Include="..\src\plans_type.h" />
<ClInclude Include="..\src\progress.h" />
<ClInclude Include="..\src\querystring_gui.h" />
<ClInclude Include="..\src\rail.h" />
@ -587,6 +591,7 @@
<ClInclude Include="..\src\signs_type.h" />
<ClInclude Include="..\src\slope_func.h" />
<ClInclude Include="..\src\slope_type.h" />
<ClInclude Include="..\src\smallmap_colours.h" />
<ClInclude Include="..\src\smallmap_gui.h" />
<ClInclude Include="..\src\sortlist_type.h" />
<ClInclude Include="..\src\sound_func.h" />
@ -723,6 +728,7 @@
<ClCompile Include="..\src\object_gui.cpp" />
<ClCompile Include="..\src\order_gui.cpp" />
<ClCompile Include="..\src\osk_gui.cpp" />
<ClCompile Include="..\src\plans_gui.cpp" />
<ClCompile Include="..\src\rail_gui.cpp" />
<ClCompile Include="..\src\road_gui.cpp" />
<ClCompile Include="..\src\roadveh_gui.cpp" />
@ -784,6 +790,7 @@
<ClInclude Include="..\src\widgets\object_widget.h" />
<ClInclude Include="..\src\widgets\order_widget.h" />
<ClInclude Include="..\src\widgets\osk_widget.h" />
<ClInclude Include="..\src\widgets\plans_widget.h" />
<ClInclude Include="..\src\widgets\rail_widget.h" />
<ClInclude Include="..\src\widgets\road_widget.h" />
<ClInclude Include="..\src\widgets\settings_widget.h" />
@ -812,6 +819,7 @@
<ClCompile Include="..\src\misc_cmd.cpp" />
<ClCompile Include="..\src\object_cmd.cpp" />
<ClCompile Include="..\src\order_cmd.cpp" />
<ClCompile Include="..\src\plans_cmd.cpp" />
<ClCompile Include="..\src\rail_cmd.cpp" />
<ClCompile Include="..\src\road_cmd.cpp" />
<ClCompile Include="..\src\roadveh_cmd.cpp" />
@ -856,6 +864,7 @@
<ClInclude Include="..\src\saveload\oldloader.h" />
<ClCompile Include="..\src\saveload\oldloader_sl.cpp" />
<ClCompile Include="..\src\saveload\order_sl.cpp" />
<ClCompile Include="..\src\saveload\plans_sl.cpp" />
<ClCompile Include="..\src\saveload\saveload.cpp" />
<ClInclude Include="..\src\saveload\saveload.h" />
<ClInclude Include="..\src\saveload\saveload_filter.h" />
@ -880,6 +889,7 @@
<ClInclude Include="..\src\table\cargo_const.h" />
<ClInclude Include="..\src\table\clear_land.h" />
<ClInclude Include="..\src\table\control_codes.h" />
<ClInclude Include="..\src\table\darklight_colours.h" />
<ClInclude Include="..\src\table\elrail_data.h" />
<ClInclude Include="..\src\table\engines.h" />
<ClInclude Include="..\src\table\genland.h" />

@ -300,6 +300,9 @@
<ClCompile Include="..\src\pbs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\plans.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\progress.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -900,6 +903,15 @@
<ClInclude Include="..\src\pbs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\plans_base.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\plans_func.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\plans_type.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\progress.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -990,6 +1002,9 @@
<ClInclude Include="..\src\slope_type.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\smallmap_colours.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\smallmap_gui.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -1398,6 +1413,9 @@
<ClCompile Include="..\src\osk_gui.cpp">
<Filter>GUI Source Code</Filter>
</ClCompile>
<ClCompile Include="..\src\plans_gui.cpp">
<Filter>GUI Source Code</Filter>
</ClCompile>
<ClCompile Include="..\src\rail_gui.cpp">
<Filter>GUI Source Code</Filter>
</ClCompile>
@ -1581,6 +1599,9 @@
<ClInclude Include="..\src\widgets\osk_widget.h">
<Filter>Widgets</Filter>
</ClInclude>
<ClInclude Include="..\src\widgets\plans_widget.h">
<Filter>Widgets</Filter>
</ClInclude>
<ClInclude Include="..\src\widgets\rail_widget.h">
<Filter>Widgets</Filter>
</ClInclude>
@ -1665,6 +1686,9 @@
<ClCompile Include="..\src\order_cmd.cpp">
<Filter>Command handlers</Filter>
</ClCompile>
<ClCompile Include="..\src\plans_cmd.cpp">
<Filter>Command handlers</Filter>
</ClCompile>
<ClCompile Include="..\src\rail_cmd.cpp">
<Filter>Command handlers</Filter>
</ClCompile>
@ -1797,6 +1821,9 @@
<ClCompile Include="..\src\saveload\order_sl.cpp">
<Filter>Save/Load handlers</Filter>
</ClCompile>
<ClCompile Include="..\src\saveload\plans_sl.cpp">
<Filter>Save/Load handlers</Filter>
</ClCompile>
<ClCompile Include="..\src\saveload\saveload.cpp">
<Filter>Save/Load handlers</Filter>
</ClCompile>
@ -1869,6 +1896,9 @@
<ClInclude Include="..\src\table\control_codes.h">
<Filter>Tables</Filter>
</ClInclude>
<ClInclude Include="..\src\table\darklight_colours.h">
<Filter>Tables</Filter>
</ClInclude>
<ClInclude Include="..\src\table\elrail_data.h">
<Filter>Tables</Filter>
</ClInclude>

@ -698,6 +698,10 @@
RelativePath=".\..\src\pbs.cpp"
>
</File>
<File
RelativePath=".\..\src\plans.cpp"
>
</File>
<File
RelativePath=".\..\src\progress.cpp"
>
@ -1502,6 +1506,18 @@
RelativePath=".\..\src\pbs.h"
>
</File>
<File
RelativePath=".\..\src\plans_base.h"
>
</File>
<File
RelativePath=".\..\src\plans_func.h"
>
</File>
<File
RelativePath=".\..\src\plans_type.h"
>
</File>
<File
RelativePath=".\..\src\progress.h"
>
@ -1622,6 +1638,10 @@
RelativePath=".\..\src\slope_type.h"
>
</File>
<File
RelativePath=".\..\src\smallmap_colours.h"
>
</File>
<File
RelativePath=".\..\src\smallmap_gui.h"
>
@ -2174,6 +2194,10 @@
RelativePath=".\..\src\osk_gui.cpp"
>
</File>
<File
RelativePath=".\..\src\plans_gui.cpp"
>
</File>
<File
RelativePath=".\..\src\rail_gui.cpp"
>
@ -2422,6 +2446,10 @@
RelativePath=".\..\src\widgets\osk_widget.h"
>
</File>
<File
RelativePath=".\..\src\widgets\plans_widget.h"
>
</File>
<File
RelativePath=".\..\src\widgets\rail_widget.h"
>
@ -2538,6 +2566,10 @@
RelativePath=".\..\src\order_cmd.cpp"
>
</File>
<File
RelativePath=".\..\src\plans_cmd.cpp"
>
</File>
<File
RelativePath=".\..\src\rail_cmd.cpp"
>
@ -2718,6 +2750,10 @@
RelativePath=".\..\src\saveload\order_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\plans_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\saveload.cpp"
>
@ -2818,6 +2854,10 @@
RelativePath=".\..\src\table\control_codes.h"
>
</File>
<File
RelativePath=".\..\src\table\darklight_colours.h"
>
</File>
<File
RelativePath=".\..\src\table\elrail_data.h"
>

@ -695,6 +695,10 @@
RelativePath=".\..\src\pbs.cpp"
>
</File>
<File
RelativePath=".\..\src\plans.cpp"
>
</File>
<File
RelativePath=".\..\src\progress.cpp"
>
@ -1499,6 +1503,18 @@
RelativePath=".\..\src\pbs.h"
>
</File>
<File
RelativePath=".\..\src\plans_base.h"
>
</File>
<File
RelativePath=".\..\src\plans_func.h"
>
</File>
<File
RelativePath=".\..\src\plans_type.h"
>
</File>
<File
RelativePath=".\..\src\progress.h"
>
@ -1619,6 +1635,10 @@
RelativePath=".\..\src\slope_type.h"
>
</File>
<File
RelativePath=".\..\src\smallmap_colours.h"
>
</File>
<File
RelativePath=".\..\src\smallmap_gui.h"
>
@ -2171,6 +2191,10 @@
RelativePath=".\..\src\osk_gui.cpp"
>
</File>
<File
RelativePath=".\..\src\plans_gui.cpp"
>
</File>
<File
RelativePath=".\..\src\rail_gui.cpp"
>
@ -2419,6 +2443,10 @@
RelativePath=".\..\src\widgets\osk_widget.h"
>
</File>
<File
RelativePath=".\..\src\widgets\plans_widget.h"
>
</File>
<File
RelativePath=".\..\src\widgets\rail_widget.h"
>
@ -2535,6 +2563,10 @@
RelativePath=".\..\src\order_cmd.cpp"
>
</File>
<File
RelativePath=".\..\src\plans_cmd.cpp"
>
</File>
<File
RelativePath=".\..\src\rail_cmd.cpp"
>
@ -2715,6 +2747,10 @@
RelativePath=".\..\src\saveload\order_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\plans_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\saveload.cpp"
>
@ -2815,6 +2851,10 @@
RelativePath=".\..\src\table\control_codes.h"
>
</File>
<File
RelativePath=".\..\src\table\darklight_colours.h"
>
</File>
<File
RelativePath=".\..\src\table\elrail_data.h"
>

@ -65,6 +65,7 @@ network/network_udp.cpp
openttd.cpp
order_backup.cpp
pbs.cpp
plans.cpp
progress.cpp
rail.cpp
rev.cpp
@ -296,6 +297,9 @@ order_base.h
order_func.h
order_type.h
pbs.h
plans_base.h
plans_func.h
plans_type.h
progress.h
querystring_gui.h
rail.h
@ -326,6 +330,7 @@ signs_func.h
signs_type.h
slope_func.h
slope_type.h
smallmap_colours.h
smallmap_gui.h
sortlist_type.h
sound_func.h
@ -481,6 +486,7 @@ news_gui.cpp
object_gui.cpp
order_gui.cpp
osk_gui.cpp
plans_gui.cpp
rail_gui.cpp
road_gui.cpp
roadveh_gui.cpp
@ -544,6 +550,7 @@ widgets/news_widget.h
widgets/object_widget.h
widgets/order_widget.h
widgets/osk_widget.h
widgets/plans_widget.h
widgets/rail_widget.h
widgets/road_widget.h
widgets/settings_widget.h
@ -574,6 +581,7 @@ industry_cmd.cpp
misc_cmd.cpp
object_cmd.cpp
order_cmd.cpp
plans_cmd.cpp
rail_cmd.cpp
road_cmd.cpp
roadveh_cmd.cpp
@ -620,6 +628,7 @@ saveload/oldloader.cpp
saveload/oldloader.h
saveload/oldloader_sl.cpp
saveload/order_sl.cpp
saveload/plans_sl.cpp
saveload/saveload.cpp
saveload/saveload.h
saveload/saveload_filter.h
@ -646,6 +655,7 @@ table/build_industry.h
table/cargo_const.h
table/clear_land.h
table/control_codes.h
table/darklight_colours.h
table/elrail_data.h
table/engines.h
table/genland.h

@ -62,7 +62,7 @@ static void PlaceAirport(TileIndex tile)
uint32 p1 = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index)->GetIndex();
p1 |= _selected_airport_layout << 8;
CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_AIRPORT | CMD_MSG(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE), CcBuildAirport, "" };
CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_AIRPORT | CMD_MSG(STR_ERROR_CAN_T_BUILD_AIRPORT_HERE), CcBuildAirport, 0, "" };
ShowSelectStationIfNeeded(cmdcont, TileArea(tile, _thd.size.x / TILE_SIZE, _thd.size.y / TILE_SIZE));
}

@ -37,7 +37,7 @@ void DeleteAnimatedTile(TileIndex tile)
*/
memmove(ti, ti + 1, (_animated_tile_list + _animated_tile_count - (ti + 1)) * sizeof(*ti));
_animated_tile_count--;
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
return;
}
}
@ -50,7 +50,7 @@ void DeleteAnimatedTile(TileIndex tile)
*/
void AddAnimatedTile(TileIndex tile)
{
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
for (const TileIndex *ti = _animated_tile_list; ti < _animated_tile_list + _animated_tile_count; ti++) {
if (tile == *ti) return;

@ -317,6 +317,50 @@ void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8 colour)
this->anim_buf[((uint32 *)video - (uint32 *)_screen.dst_ptr) + x + y * this->anim_buf_width] = colour | (DEFAULT_BRIGHTNESS << 8);
}
void Blitter_32bppAnim::SetLine(void *video, int x, int y, uint8 *colours, uint width)
{
Colour *dst = (Colour *)video + x + y * _screen.pitch;
if (_screen_disable_anim) {
do {
*dst = LookupColourInPalette(*colours);
dst++;
colours++;
} while (--width);
} else {
uint16 *dstanim = (uint16 *)(&this->anim_buf[(uint32 *)video - (uint32 *)_screen.dst_ptr + x + y * _screen.pitch]);
do {
*dstanim = *colours | (DEFAULT_BRIGHTNESS << 8);
*dst = LookupColourInPalette(*colours);
dst++;
dstanim++;
colours++;
} while (--width);
}
}
void Blitter_32bppAnim::SetLine32(void *video, int x, int y, uint32 *colours, uint width)
{
Colour *dst = (Colour *)video + x + y * _screen.pitch;
if (_screen_disable_anim) {
do {
*dst = *colours;
dst++;
colours++;
} while (--width);
} else {
uint16 *dstanim = (uint16 *)(&this->anim_buf[(uint32 *)video - (uint32 *)_screen.dst_ptr + x + y * _screen.pitch]);
do {
*dstanim = 0;
*dst = *colours;
dst++;
dstanim++;
colours++;
} while (--width);
}
}
void Blitter_32bppAnim::DrawRect(void *video, int width, int height, uint8 colour)
{
if (_screen_disable_anim) {

@ -32,6 +32,8 @@ public:
/* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom);
/* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal);
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
/* virtual */ void SetLine(void *video, int x, int y, uint8 *colours, uint width);
/* virtual */ void SetLine32(void *video, int x, int y, uint32 *colours, uint width);
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
/* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);

@ -24,6 +24,26 @@ void Blitter_32bppBase::SetPixel(void *video, int x, int y, uint8 colour)
*((Colour *)video + x + y * _screen.pitch) = LookupColourInPalette(colour);
}
void Blitter_32bppBase::SetLine(void *video, int x, int y, uint8 *colours, uint width)
{
Colour *dst = (Colour *)video + x + y * _screen.pitch;
do {
*dst = LookupColourInPalette(*colours);
dst++;
colours++;
} while (--width);
}
void Blitter_32bppBase::SetLine32(void *video, int x, int y, uint32 *colours, uint width)
{
Colour *dst = (Colour *)video + x + y * _screen.pitch;
do {
*dst = *colours;
dst++;
colours++;
} while (--width);
}
void Blitter_32bppBase::DrawRect(void *video, int width, int height, uint8 colour)
{
Colour colour32 = LookupColourInPalette(colour);

@ -23,6 +23,8 @@ public:
/* virtual */ uint8 GetScreenDepth() { return 32; }
/* virtual */ void *MoveTo(void *video, int x, int y);
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
/* virtual */ void SetLine(void *video, int x, int y, uint8 *colours, uint width);
/* virtual */ void SetLine32(void *video, int x, int y, uint32 *colours, uint width);
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
/* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);

@ -280,8 +280,8 @@ Sprite *Blitter_32bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloc
zoom_max = ZOOM_LVL_NORMAL;
} else {
zoom_min = _settings_client.gui.zoom_min;
zoom_max = _settings_client.gui.zoom_max;
if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_MAX;
zoom_max = (ZoomLevel) min(_settings_client.gui.zoom_max, ZOOM_LVL_DRAW_SPR);
if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_DRAW_SPR;
}
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {

@ -35,6 +35,11 @@ void Blitter_8bppBase::SetPixel(void *video, int x, int y, uint8 colour)
*((uint8 *)video + x + y * _screen.pitch) = colour;
}
void Blitter_8bppBase::SetLine(void *video, int x, int y, uint8 *colours, uint width)
{
memcpy((uint8 *)video + x + y * _screen.pitch, colours, width * sizeof(uint8));
}
void Blitter_8bppBase::DrawRect(void *video, int width, int height, uint8 colour)
{
do {

@ -21,6 +21,7 @@ public:
/* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal);
/* virtual */ void *MoveTo(void *video, int x, int y);
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour);
/* virtual */ void SetLine(void *video, int x, int y, uint8 *colours, uint width);
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour);
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height);
/* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height);

@ -134,8 +134,8 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloca
zoom_max = ZOOM_LVL_NORMAL;
} else {
zoom_min = _settings_client.gui.zoom_min;
zoom_max = _settings_client.gui.zoom_max;
if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_MAX;
zoom_max = (ZoomLevel) min(_settings_client.gui.zoom_max, ZOOM_LVL_DRAW_SPR);
if (zoom_max == zoom_min) zoom_max = ZOOM_LVL_DRAW_SPR;
}
for (ZoomLevel i = zoom_min; i <= zoom_max; i++) {

@ -100,6 +100,26 @@ public:
*/
virtual void SetPixel(void *video, int x, int y, uint8 colour) = 0;
/**
* Draw a sequence of pixels on the video-buffer.
* @param video The destination pointer (video-buffer).
* @param x The x position within video-buffer.
* @param y The y position within video-buffer.
* @param colours A 8bpp colour mapping buffer.
* @param width The length of the line.
*/
virtual void SetLine(void *video, int x, int y, uint8 *colours, uint width) = 0;
/**
* Draw a sequence of pixels on the video-buffer (no LookupColourInPalette).
* @param video The destination pointer (video-buffer).
* @param x The x position within video-buffer.
* @param y The y position within video-buffer.
* @param colours A 32bpp colour buffer.
* @param width The length of the line.
*/
virtual void SetLine32(void *video, int x, int y, uint32 *colours, uint width) { NOT_REACHED(); };
/**
* Make a single horizontal line in a single colour on the video-buffer.
* @param video The destination pointer (video-buffer).

@ -23,6 +23,7 @@ public:
/* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator);
/* virtual */ void *MoveTo(void *video, int x, int y) { return NULL; };
/* virtual */ void SetPixel(void *video, int x, int y, uint8 colour) {};
/* virtual */ void SetLine(void *video, int x, int y, uint8 *colours, uint width) {};
/* virtual */ void DrawRect(void *video, int width, int height, uint8 colour) {};
/* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) {};
/* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height) {};

@ -46,20 +46,45 @@ static CommandCost ClearTile_Clear(TileIndex tile, DoCommandFlag flags)
return price;
}
SpriteID GetSpriteIDForClearLand(const Slope slope, byte set)
{
return SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(slope) + set * 19;
}
void DrawClearLandTile(const TileInfo *ti, byte set)
{
DrawGroundSprite(SPR_FLAT_BARE_LAND + SlopeToSpriteOffset(ti->tileh) + set * 19, PAL_NONE);
DrawGroundSprite(GetSpriteIDForClearLand(ti->tileh, set), PAL_NONE);
}
void DrawHillyLandTile(const TileInfo *ti)
SpriteID GetSpriteIDForHillyLand(const Slope slope, const uint rough_index)
{
if (ti->tileh != SLOPE_FLAT) {
DrawGroundSprite(SPR_FLAT_ROUGH_LAND + SlopeToSpriteOffset(ti->tileh), PAL_NONE);
if (slope != SLOPE_FLAT) {
return SPR_FLAT_ROUGH_LAND + SlopeToSpriteOffset(slope);
} else {
DrawGroundSprite(_landscape_clear_sprites_rough[GB(ti->x ^ ti->y, 4, 3)], PAL_NONE);
return _landscape_clear_sprites_rough[rough_index];
}
}
void DrawHillyLandTile(const TileInfo *ti)
{
DrawGroundSprite(GetSpriteIDForHillyLand(ti->tileh, GB(ti->x ^ ti->y, 4, 3)), PAL_NONE);
}
SpriteID GetSpriteIDForRocks(const Slope slope, const uint tile_hash)
{
return (tile_hash & 1 ? SPR_FLAT_ROCKY_LAND_2 : SPR_FLAT_ROCKY_LAND_1) + SlopeToSpriteOffset(slope);
}
SpriteID GetSpriteIDForFields(const Slope slope, const uint field_type)
{
return _clear_land_sprites_farmland[field_type] + SlopeToSpriteOffset(slope);
}
SpriteID GetSpriteIDForSnowDesert(const Slope slope, const uint density)
{
return _clear_land_sprites_snow_desert[density] + SlopeToSpriteOffset(slope);
}
static void DrawClearLandFence(const TileInfo *ti)
{
/* combine fences into one sprite object */
@ -112,17 +137,17 @@ static void DrawTile_Clear(TileInfo *ti)
break;
case CLEAR_ROCKS:
DrawGroundSprite((TileHash(ti->x, ti->y) & 1 ? SPR_FLAT_ROCKY_LAND_2 : SPR_FLAT_ROCKY_LAND_1) + SlopeToSpriteOffset(ti->tileh), PAL_NONE);
DrawGroundSprite(GetSpriteIDForRocks(ti->tileh, TileHash(ti->x, ti->y)), PAL_NONE);
break;
case CLEAR_FIELDS:
DrawGroundSprite(_clear_land_sprites_farmland[GetFieldType(ti->tile)] + SlopeToSpriteOffset(ti->tileh), PAL_NONE);
DrawGroundSprite(GetSpriteIDForFields(ti->tileh, GetFieldType(ti->tile)), PAL_NONE);
DrawClearLandFence(ti);
break;
case CLEAR_SNOW:
case CLEAR_DESERT:
DrawGroundSprite(_clear_land_sprites_snow_desert[GetClearDensity(ti->tile)] + SlopeToSpriteOffset(ti->tileh), PAL_NONE);
DrawGroundSprite(GetSpriteIDForSnowDesert(ti->tileh, GetClearDensity(ti->tile)), PAL_NONE);
break;
}
@ -171,7 +196,7 @@ static void UpdateFences(TileIndex tile)
dirty = true;
}
if (dirty) MarkTileDirtyByTile(tile);
if (dirty) MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
@ -253,7 +278,6 @@ static void TileLoop_Clear(TileIndex tile)
int z;
if (IsTileFlat(tile, &z) && z == 0) {
DoFloodTile(tile);
MarkTileDirtyByTile(tile);
return;
}
}
@ -307,7 +331,7 @@ static void TileLoop_Clear(TileIndex tile)
return;
}
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
void GenerateClearTile()

@ -17,4 +17,10 @@
void DrawHillyLandTile(const TileInfo *ti);
void DrawClearLandTile(const TileInfo *ti, byte set);
SpriteID GetSpriteIDForClearLand(const Slope slope, byte set);
SpriteID GetSpriteIDForHillyLand(const Slope slope, const uint rough_index);
SpriteID GetSpriteIDForRocks(const Slope slope, const uint tile_hash);
SpriteID GetSpriteIDForFields(const Slope slope, const uint field_type);
SpriteID GetSpriteIDForSnowDesert(const Slope slope, const uint density);
#endif /* CLEAR_FUNC_H */

@ -198,6 +198,12 @@ CommandProc CmdSetTimetableStart;
CommandProc CmdOpenCloseAirport;
CommandProc CmdAddPlan;
CommandProc CmdAddPlanLine;
CommandProc CmdRemovePlan;
CommandProc CmdRemovePlanLine;
CommandProc CmdChangePlanVisibility;
#define DEF_CMD(proc, flags, type) {proc, #proc, (CommandFlags)flags, type}
/**
@ -354,6 +360,12 @@ static const Command _command_proc_table[] = {
DEF_CMD(CmdSetTimetableStart, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_TIMETABLE_START
DEF_CMD(CmdOpenCloseAirport, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_OPEN_CLOSE_AIRPORT
DEF_CMD(CmdAddPlan, 0, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN
DEF_CMD(CmdAddPlanLine, 0, CMDT_OTHER_MANAGEMENT ), // CMD_ADD_PLAN_LINE
DEF_CMD(CmdRemovePlan, 0, CMDT_OTHER_MANAGEMENT ), // CMD_REMOVE_PLAN
DEF_CMD(CmdRemovePlanLine, 0, CMDT_OTHER_MANAGEMENT ), // CMD_REMOVE_PLAN_LINE
DEF_CMD(CmdChangePlanVisibility, 0, CMDT_OTHER_MANAGEMENT ), // CMD_CHANGE_PLAN_VISIBILITY
};
/*!
@ -542,9 +554,10 @@ bool DoCommandP(const CommandContainer *container, bool my_cmd)
* @param callback A callback function to call after the command is finished
* @param text The text to pass
* @param my_cmd indicator if the command is from a company or server (to display error messages for a user)
* @param binary_length The quantity of binary data in text
* @return \c true if the command succeeded, else \c false.
*/
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd)
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, uint32 binary_length)
{
/* Cost estimation is generally only done when the
* local user presses shift while doing somthing.
@ -574,7 +587,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac
if (!(cmd & CMD_NETWORK_COMMAND) && GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = CLIENT_ID_SERVER;
#endif
CommandCost res = DoCommandPInternal(tile, p1, p2, cmd, callback, text, my_cmd, estimate_only);
CommandCost res = DoCommandPInternal(tile, p1, p2, cmd, callback, text, my_cmd, estimate_only, binary_length);
if (res.Failed()) {
/* Only show the error when it's for us. */
StringID error_part1 = GB(cmd, 16, 16);
@ -620,7 +633,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac
* @param estimate_only whether to give only the estimate or also execute the command
* @return the command cost of this function.
*/
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only)
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only, uint32 binary_length)
{
/* Prevent recursion; it gives a mess over the network */
assert(_docommand_recursive == 0);
@ -699,7 +712,7 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
* send it to the command-queue and abort execution
*/
if (_networking && !_generating_world && !(cmd & CMD_NETWORK_COMMAND)) {
NetworkSendCommand(tile, p1, p2, cmd & ~CMD_FLAGS_MASK, callback, text, _current_company);
NetworkSendCommand(tile, p1, p2, cmd & ~CMD_FLAGS_MASK, callback, text, _current_company, binary_length);
cur_company.Restore();
/* Don't return anything special here; no error, no costs.

@ -37,13 +37,13 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID);
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text = NULL);
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags);
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = NULL, const char *text = NULL, bool my_cmd = true);
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = NULL, const char *text = NULL, bool my_cmd = true, uint32 binary_length = 0);
bool DoCommandP(const CommandContainer *container, bool my_cmd = true);
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only);
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only, uint32 binary_length);
#ifdef ENABLE_NETWORK
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company);
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company, uint32 binary_length);
#endif /* ENABLE_NETWORK */
extern Money _additional_cash_required;
@ -102,6 +102,9 @@ CommandCallback CcPlaceSign;
CommandCallback CcTerraform;
CommandCallback CcGiveMoney;
/* plans_gui.cpp */
CommandCallback CcAddPlan;
/* rail_gui.cpp */
CommandCallback CcPlaySound1E;
CommandCallback CcRailDepot;

@ -329,6 +329,12 @@ enum Commands {
CMD_OPEN_CLOSE_AIRPORT, ///< open/close an airport to incoming aircraft
CMD_ADD_PLAN,
CMD_ADD_PLAN_LINE,
CMD_REMOVE_PLAN,
CMD_REMOVE_PLAN_LINE,
CMD_CHANGE_PLAN_VISIBILITY,
CMD_END, ///< Must ALWAYS be on the end of this list!! (period)
};
@ -466,6 +472,8 @@ struct Command {
*/
typedef void CommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2);
#define MAX_CMD_TEXT_LENGTH 32000
/**
* Structure for buffering the build command when selecting a station to join.
*/
@ -475,7 +483,8 @@ struct CommandContainer {
uint32 p2; ///< parameter p2.
uint32 cmd; ///< command being executed.
CommandCallback *callback; ///< any callback function executed upon successful completion of the command.
char text[32 * MAX_CHAR_LENGTH]; ///< possible text sent for name changes etc, in bytes including '\0'.
uint32 binary_length; ///< in case text contains binary data, this describes its length.
char text[MAX_CMD_TEXT_LENGTH]; ///< possible text sent for name changes etc, in bytes including '\0'.
};
#endif /* COMMAND_TYPE_H */

@ -374,7 +374,7 @@ struct IConsoleWindow : Window
this->Scroll(-wheel);
}
virtual void OnFocusLost()
virtual void OnFocusLost(Window *newly_focused_window)
{
VideoDriver::GetInstance()->EditBoxLostFocus();
}

@ -190,7 +190,7 @@ struct BuildDocksToolbarWindow : Window {
uint32 p2 = (uint32)INVALID_STATION << 16; // no station to join
/* tile is always the land tile, so need to evaluate _thd.pos */
CommandContainer cmdcont = { tile, _ctrl_pressed, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, "" };
CommandContainer cmdcont = { tile, _ctrl_pressed, p2, CMD_BUILD_DOCK | CMD_MSG(STR_ERROR_CAN_T_BUILD_DOCK_HERE), CcBuildDocks, 0, "" };
/* Determine the watery part of the dock. */
DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));

@ -1195,6 +1195,9 @@ void ScreenSizeChanged()
_dirty_bytes_per_line = CeilDiv(_screen.width, DIRTY_BLOCK_WIDTH);
_dirty_blocks = ReallocT<byte>(_dirty_blocks, _dirty_bytes_per_line * CeilDiv(_screen.height, DIRTY_BLOCK_HEIGHT));
extern uint32 *_vp_map_line;
_vp_map_line = ReallocT<uint32>(_vp_map_line, _screen.width);
/* check the dirty rect */
if (_invalid_rect.right >= _screen.width) _invalid_rect.right = _screen.width;
if (_invalid_rect.bottom >= _screen.height) _invalid_rect.bottom = _screen.height;

@ -19,6 +19,12 @@
#include "blitter/factory.hpp"
#include "video/video_driver.hpp"
#include "window_func.h"
#include "zoom_func.h"
#include "clear_map.h"
#include "clear_func.h"
#include "tree_map.h"
#include "table/tree_land.h"
#include "blitter/32bpp_base.hpp"
/* The type of set we're replacing */
#define SET_TYPE "graphics"
@ -193,6 +199,9 @@ static void LoadSpriteTables()
);
}
/* Load route step graphics */
LoadGrfFile("route_step.grf", SPR_ROUTE_STEP_BASE, i++);
/* Initialize the unicode to sprite mapping table */
InitializeUnicodeGlyphMap();
@ -308,6 +317,103 @@ void CheckBlitter()
ReInitAllWindows();
}
static void UpdateRouteStepSpriteSize()
{
extern uint _vp_route_step_width;
extern uint _vp_route_step_height_top;
extern uint _vp_route_step_height_middle;
extern uint _vp_route_step_height_bottom;
extern SubSprite _vp_route_step_subsprite;
Dimension d = GetSpriteSize(SPR_ROUTE_STEP_TOP);
_vp_route_step_width = d.width;
_vp_route_step_height_top = d.height;
d = GetSpriteSize(SPR_ROUTE_STEP_MIDDLE);
_vp_route_step_height_middle = d.height;
assert(_vp_route_step_width == d.width);
d = GetSpriteSize(SPR_ROUTE_STEP_BOTTOM);
_vp_route_step_height_bottom = d.height;
assert(_vp_route_step_width == d.width);
const int char_height = GetCharacterHeight(FS_SMALL) + 1;
_vp_route_step_subsprite.right = ScaleByZoom(_vp_route_step_width, ZOOM_LVL_GUI);
_vp_route_step_subsprite.bottom = ScaleByZoom(char_height, ZOOM_LVL_GUI);
_vp_route_step_subsprite.left = 0;
_vp_route_step_subsprite.top = 0;
}
/* multi can be density, field type, ... */
static SpriteID GetSpriteIDForClearGround(const ClearGround cg, const Slope slope, const uint multi)
{
switch (cg) {
case CLEAR_GRASS:
return GetSpriteIDForClearLand(slope, (byte) multi);
case CLEAR_ROUGH:
return GetSpriteIDForHillyLand(slope, multi);
case CLEAR_ROCKS:
return GetSpriteIDForRocks(slope, multi);
case CLEAR_FIELDS:
return GetSpriteIDForFields(slope, multi);
case CLEAR_SNOW:
case CLEAR_DESERT:
return GetSpriteIDForSnowDesert(slope, multi);
default: NOT_REACHED();
}
}
/** Once the sprites are loaded, we can determine main colours of ground/water/... */
void GfxDetermineMainColours()
{
/* Water. */
extern uint32 _vp_map_water_colour[5];
_vp_map_water_colour[0] = GetSpriteMainColour(SPR_FLAT_WATER_TILE, PAL_NONE);
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 32) {
_vp_map_water_colour[1] = Blitter_32bppBase::MakeTransparent(_vp_map_water_colour[0], 256, 192).data; // lighter
_vp_map_water_colour[2] = Blitter_32bppBase::MakeTransparent(_vp_map_water_colour[0], 192, 256).data; // darker
_vp_map_water_colour[3] = _vp_map_water_colour[2];
_vp_map_water_colour[4] = _vp_map_water_colour[1];
}
/* Clear ground. */
extern uint32 _vp_map_vegetation_clear_colours[16][6][8];
memset(_vp_map_vegetation_clear_colours, 0, sizeof(_vp_map_vegetation_clear_colours));
const struct {
byte min;
byte max;
} multi[6] = {
{ 0, 3 }, // CLEAR_GRASS, density
{ 0, 7 }, // CLEAR_ROUGH, "random" based on position
{ 0, 1 }, // CLEAR_ROCKS, tile hash parity
{ 0, 7 }, // CLEAR_FIELDS, some field types
{ 0, 3 }, // CLEAR_SNOW, density
{ 1, 3 }, // CLEAR_DESERT, density
};
for (uint s = 0; s <= SLOPE_ELEVATED; s++) {
for (uint cg = 0; cg < 6; cg++) {
for (uint m = multi[cg].min; m <= multi[cg].max; m++) {
_vp_map_vegetation_clear_colours[s][cg][m] = GetSpriteMainColour(GetSpriteIDForClearGround((ClearGround) cg, (Slope) s, m), PAL_NONE);
}
}
}
/* Trees. */
extern uint32 _vp_map_vegetation_tree_colours[5][MAX_TREE_COUNT_BY_LANDSCAPE];
const uint base = _tree_base_by_landscape[_settings_game.game_creation.landscape];
const uint count = _tree_count_by_landscape[_settings_game.game_creation.landscape];
for (uint tg = 0; tg < 5; tg++) {
for (uint i = base; i < base + count; i++) {
_vp_map_vegetation_tree_colours[tg][i - base] = GetSpriteMainColour(_tree_sprites[i].sprite, _tree_sprites[i].pal);
}
const int diff = MAX_TREE_COUNT_BY_LANDSCAPE - count;
if (diff > 0) {
for (uint i = count; i < MAX_TREE_COUNT_BY_LANDSCAPE; i++)
_vp_map_vegetation_tree_colours[tg][i] = _vp_map_vegetation_tree_colours[tg][i - count];
}
}
}
/** Initialise and load all the sprites. */
void GfxLoadSprites()
{
@ -318,7 +424,9 @@ void GfxLoadSprites()
GfxInitSpriteMem();
LoadSpriteTables();
GfxInitPalettes();
GfxDetermineMainColours();
UpdateRouteStepSpriteSize();
UpdateCursorSize();
}

@ -61,6 +61,8 @@ static const KeycodeNames _keycode_to_name[] = {
{"NUM_MINUS", WKC_NUM_MINUS},
{"=", WKC_EQUALS},
{"-", WKC_MINUS},
{"PAGE_UP", WKC_PAGEUP},
{"PAGE_DOWN", WKC_PAGEDOWN},
};
/**

@ -523,7 +523,7 @@ static void TransportIndustryGoods(TileIndex tile)
ResetIndustryConstructionStage(tile);
SetIndustryCompleted(tile);
SetIndustryGfx(tile, newgfx);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
}
}
@ -556,7 +556,7 @@ static void AnimateTile_Industry(TileIndex tile)
}
SetAnimationFrame(tile, m);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
break;
@ -574,7 +574,7 @@ static void AnimateTile_Industry(TileIndex tile)
}
SetAnimationFrame(tile, m);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
break;
@ -588,7 +588,7 @@ static void AnimateTile_Industry(TileIndex tile)
}
SetAnimationFrame(tile, m);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
break;
@ -601,7 +601,7 @@ static void AnimateTile_Industry(TileIndex tile)
DeleteAnimatedTile(tile);
} else {
SetAnimationFrame(tile, m + 1);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
}
break;
@ -627,7 +627,7 @@ static void AnimateTile_Industry(TileIndex tile)
}
SetAnimationFrame(tile, m);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
break;
@ -640,7 +640,7 @@ static void AnimateTile_Industry(TileIndex tile)
gfx = (gfx < 155) ? gfx + 1 : 148;
SetIndustryGfx(tile, gfx);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
break;
@ -659,7 +659,7 @@ static void AnimateTile_Industry(TileIndex tile)
} else {
SetAnimationFrame(tile, m);
SetIndustryGfx(tile, gfx);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
}
break;
@ -685,7 +685,7 @@ static void AnimateTile_Industry(TileIndex tile)
byte m = (GetAnimationFrame(tile) + 1) | 0x40;
if (m > 0xC2) m = 0xC0;
SetAnimationFrame(tile, m);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
} else if (state >= 0x200 && state < 0x3A0) {
int i = (state < 0x220 || state >= 0x380) ? 7 : 3;
if (state & i) return;
@ -693,7 +693,7 @@ static void AnimateTile_Industry(TileIndex tile)
byte m = (GetAnimationFrame(tile) & 0xBF) - 1;
if (m < 0x80) m = 0x82;
SetAnimationFrame(tile, m);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
break;
}
@ -723,7 +723,7 @@ static void MakeIndustryTileBigger(TileIndex tile)
StartStopIndustryTileAnimation(tile, IAT_CONSTRUCTION_STATE_CHANGE);
if (stage == INDUSTRY_COMPLETED) SetIndustryCompleted(tile);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
if (!IsIndustryCompleted(tile)) return;
@ -818,7 +818,7 @@ static void TileLoop_Industry(TileIndex tile)
if (newgfx != INDUSTRYTILE_NOANIM) {
ResetIndustryConstructionStage(tile);
SetIndustryGfx(tile, newgfx);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
return;
}
@ -1021,7 +1021,7 @@ static void PlantFarmField(TileIndex tile, IndustryID industry)
if (IsSuitableForFarmField(cur_tile, true)) {
MakeField(cur_tile, field_type, industry);
SetClearCounter(cur_tile, counter);
MarkTileDirtyByTile(cur_tile);
MarkTileDirtyByTile(cur_tile, ZOOM_LVL_DRAW_MAP);
}
}

@ -2285,6 +2285,14 @@ struct IndustryCargoesWindow : public Window {
/* Only notify the smallmap window if it exists. In particular, do not
* bring it to the front to prevent messing up any nice layout of the user. */
InvalidateWindowClassesData(WC_SMALLMAP, 0);
/* Notify viewports too. */
Window *w;
FOR_ALL_WINDOWS_FROM_BACK(w) {
if (w->viewport != NULL)
if (w->viewport->zoom >= ZOOM_LVL_DRAW_MAP && w->viewport->map_type == VPMT_INDUSTRY)
w->InvalidateData();
}
}
/**

@ -400,6 +400,7 @@ STR_MAP_MENU_MAP_OF_WORLD :Map of world
STR_MAP_MENU_EXTRA_VIEW_PORT :Extra viewport
STR_MAP_MENU_LINGRAPH_LEGEND :Cargo Flow Legend
STR_MAP_MENU_SIGN_LIST :Sign list
STR_MAP_MENU_PLAN_LIST :Plan list
############ range for town menu starts
STR_TOWN_MENU_TOWN_DIRECTORY :Town directory
@ -1367,6 +1368,32 @@ STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :Disabled
STR_CONFIG_SETTING_OSK_ACTIVATION_DOUBLE_CLICK :Double click
STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK_FOCUS :Single click (when focussed)
STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK :Single click (immediately)
STR_CONFIG_SETTING_SHOW_VEHICLE_ROUTE_STEPS :Show the vehicle's route steps: {STRING2}
STR_CONFIG_SETTING_VIEWPORT_MAP_SCAN_SURROUNDINGS :Scan surroundings (better for high zoom out levels): {STRING2}
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SLOPES :Show slopes: {STRING2}
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_BRIDGES :Show bridges: {STRING2}
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_TUNNELS :Show tunnels: {STRING2}
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SCROLLING_VP :Show scrolling viewport: {STRING2}
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SCROLLING_VP_NOTHING :No
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SCROLLING_VP_CONTOUR :Contour
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SCROLLING_VP_BLEND :Blend with some white (32bpp only)
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SCROLLING_VP_ALL :Blend + contour
STR_CONFIG_SETTING_VIEWPORT_MAP_USE_OWNER_COLOUR_BRIDGE_TUNNEL :Use owner's colour for bridges and tunnels: {STRING2}
STR_CONFIG_SETTING_VIEWPORT_MAP_DEFAULT_MODE :Default mode: {STRING2}
STR_CONFIG_SETTING_VIEWPORT_MAP_DEFAULT_MODE_VEGETATION :Vegetation
STR_CONFIG_SETTING_VIEWPORT_MAP_DEFAULT_MODE_OWNER :Owner
STR_CONFIG_SETTING_VIEWPORT_MAP_DEFAULT_MODE_INDUSTRY :Industry
STR_CONFIG_SETTING_VIEWPORT_MAP_ACTION_DBLCLICK :Function of double-click: {STRING2}
STR_CONFIG_SETTING_VIEWPORT_MAP_ACTION_DBLCLICK_DO_NOTHING :Do nothing
STR_CONFIG_SETTING_VIEWPORT_MAP_ACTION_DBLCLICK_ZOOM_MAIN :Zoom in directly to 1X
STR_CONFIG_SETTING_VIEWPORT_MAP_ACTION_DBLCLICK_NEW_EXTRA :Open an extra viewport
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_VEHICLE_ROUTE :Show the vehicle's route: {STRING2}
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_VEHICLE_ROUTE_NO :No
STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_VEHICLE_ROUTE_SIMPLE :Simple
STR_CONFIG_SETTING_VIEWPORT_MAP_DRAW_ROUTE_DASH :Drawing style of vehicle's route: {STRING}
STR_CONFIG_SETTING_VIEWPORT_MAP_DRAW_ROUTE_DASH_VALUE :dashed lines of {COMMA} pixel{P "" s}
STR_CONFIG_SETTING_VIEWPORT_MAP_DRAW_ROUTE_DASH_DISABLED :plain lines
STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU :Right-click emulation: {STRING2}
STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU_HELPTEXT :Select the method to emulate right mouse-button clicks
@ -1594,6 +1621,10 @@ STR_CONFIG_SETTING_ZOOM_LVL_NORMAL :Normal
STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X :2x
STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X :4x
STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X :8x
STR_CONFIG_SETTING_ZOOM_LVL_OUT_16X :16x
STR_CONFIG_SETTING_ZOOM_LVL_OUT_32X :32x
STR_CONFIG_SETTING_ZOOM_LVL_OUT_64X :64x
STR_CONFIG_SETTING_ZOOM_LVL_OUT_128X :128x
STR_CONFIG_SETTING_TOWN_GROWTH :Town growth speed: {STRING2}
STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT :Speed of town growth
STR_CONFIG_SETTING_TOWN_GROWTH_NONE :None
@ -1691,6 +1722,7 @@ STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Industr
STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Cargo distribution
STR_CONFIG_SETTING_AI :{ORANGE}Competitors
STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computer players
STR_CONFIG_SETTING_VIEWPORT_MAP_OPTIONS :{ORANGE}Map mode
STR_CONFIG_SETTING_PATHFINDER_OPF :Original
STR_CONFIG_SETTING_PATHFINDER_NPF :NPF
@ -3288,6 +3320,14 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centre t
STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Production level: {YELLOW}{COMMA}%
STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}The industry has announced imminent closure!
# Industry tooltip
STR_INDUSTRY_VIEW_TRANSPORTED_TOOLTIP :{BLACK}{STRING}
STR_INDUSTRY_VIEW_TRANSPORTED_TOOLTIP_TOOLTIP :{BLACK}{STRING}{}{CARGO_LONG} ({COMMA}%)
STR_INDUSTRY_VIEW_TRANSPORTED_TOOLTIP_TOOLTIP_TOOLTIP :{BLACK}{STRING}{}{CARGO_LONG} ({COMMA}%){}{BLACK}{CARGO_LONG} ({COMMA}%)
# Town tooltip
STR_TOWN_NAME_TOOLTIP :{BLACK}{TOWN}
############ range for requires starts
STR_INDUSTRY_VIEW_REQUIRES_CARGO :{BLACK}Requires: {YELLOW}{STRING}{RAW_STRING}
STR_INDUSTRY_VIEW_REQUIRES_CARGO_CARGO :{BLACK}Requires: {YELLOW}{STRING}{RAW_STRING}, {STRING}{RAW_STRING}
@ -4037,6 +4077,22 @@ STR_TEXTFILE_VIEW_README :{BLACK}View rea
STR_TEXTFILE_VIEW_CHANGELOG :{BLACK}Changelog
STR_TEXTFILE_VIEW_LICENCE :{BLACK}Licence
# Plans window
STR_PLANS_CAPTION :{WHITE}Plans
STR_PLANS_NEW_PLAN :{BLACK}New
STR_PLANS_NEW_PLAN_TOOLTIP :{BLACK}Create a new plan
STR_PLANS_ADD_LINES :{BLACK}Add lines
STR_PLANS_ADDING_LINES :{BLACK}Adding...
STR_PLANS_HIDE_ALL :{BLACK}Hide all
STR_PLANS_HIDE_ALL_TOOLTIP :{BLACK}Set the visibility of all the plans and all their lines to false
STR_PLANS_VISIBILITY_PRIVATE :{BLACK}Make private
STR_PLANS_VISIBILITY_PUBLIC :{BLACK}Make public
STR_PLANS_VISIBILITY_TOOLTIP :{BLACK}Toggle the visibility of a plan (private is yellow, public is blue). A public plan will be displayed in the plan window of the other companies but only its owner can add lines to it.
STR_PLANS_DELETE :{BLACK}Delete
STR_PLANS_DELETE_TOOLTIP :{BLACK}Delete the selected item in the list
STR_PLANS_LIST_ITEM_PLAN :Plan #{NUM}: {NUM} line{P "" s} ({DATE_SHORT})
STR_PLANS_LIST_ITEM_LINE : -- Line #{NUM}: {NUM} segment{P "" s}
STR_PLANS_LIST_TOOLTIP :{BLACK}Double click any item in the list to (un)fold the related plan
# Vehicle loading indicators
STR_PERCENT_UP_SMALL :{TINY_FONT}{WHITE}{NUM}%{UP_ARROW}
@ -4460,6 +4516,11 @@ STR_ERROR_CAN_T_PLACE_SIGN_HERE :{WHITE}Can't pl
STR_ERROR_CAN_T_CHANGE_SIGN_NAME :{WHITE}Can't change sign name...
STR_ERROR_CAN_T_DELETE_SIGN :{WHITE}Can't delete sign...
# Plan related errors
STR_ERROR_TOO_MANY_PLANS :{WHITE}... too many plans
STR_ERROR_TOO_MANY_NODES :{WHITE}... too many nodes in plan line
STR_ERROR_NO_MORE_SPACE_FOR_LINES :{WHITE}No more space for lines
# Translatable comment for OpenTTD's desktop shortcut
STR_DESKTOP_SHORTCUT_COMMENT :A simulation game based on Transport Tycoon Deluxe
@ -4879,6 +4940,12 @@ STR_SAVEGAME_NAME_DEFAULT :{COMPANY}, {STR
STR_SAVEGAME_NAME_SPECTATOR :Spectator, {1:STRING1}
# Viewport strings
STR_VIEWPORT_SHOW_VEHICLE_ROUTE_STEP :{BROWN}{NUM} {STRING}
STR_VIEWPORT_SHOW_VEHICLE_ROUTE_STEP_STATION :{BLACK}ST
STR_VIEWPORT_SHOW_VEHICLE_ROUTE_STEP_WAYPOINT :{GRAY}WP
STR_VIEWPORT_SHOW_VEHICLE_ROUTE_STEP_IMPLICIT :{GRAY}IM
STR_VIEWPORT_SHOW_VEHICLE_ROUTE_STEP_DEPOT :{RED}DE
STR_VIEWPORT_TOWN_POP :{WHITE}{TOWN} ({COMMA})
STR_VIEWPORT_TOWN :{WHITE}{TOWN}
STR_VIEWPORT_TOWN_TINY_BLACK :{TINY_FONT}{BLACK}{TOWN}

@ -231,6 +231,8 @@ enum {
GHK_CHAT_ALL,
GHK_CHAT_COMPANY,
GHK_CHAT_SERVER,
GHK_CHANGE_MAP_MODE_PREV,
GHK_CHANGE_MAP_MODE_NEXT,
};
struct MainWindow : Window
@ -249,6 +251,7 @@ struct MainWindow : Window
NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_M_VIEWPORT);
nvp->InitializeViewport(this, TileXY(32, 32), ZOOM_LVL_VIEWPORT);
this->viewport->map_type = (ViewportMapType) _settings_client.gui.default_viewport_map_mode;
this->viewport->overlay = new LinkGraphOverlay(this, WID_M_VIEWPORT, 0, 0, 3);
this->refresh = LINKGRAPH_DELAY;
}
@ -423,6 +426,25 @@ struct MainWindow : Window
break;
#endif
case GHK_CHANGE_MAP_MODE_PREV:
if (_focused_window && _focused_window->viewport && _focused_window->viewport->zoom >= ZOOM_LVL_DRAW_MAP) {
_focused_window->viewport->map_type = ChangeRenderMode(_focused_window->viewport, true);
_focused_window->SetDirty();
} else if (this->viewport->zoom >= ZOOM_LVL_DRAW_MAP) {
this->viewport->map_type = ChangeRenderMode(this->viewport, true);
this->SetDirty();
}
break;
case GHK_CHANGE_MAP_MODE_NEXT:
if (_focused_window && _focused_window->viewport && _focused_window->viewport->zoom >= ZOOM_LVL_DRAW_MAP) {
_focused_window->viewport->map_type = ChangeRenderMode(_focused_window->viewport, false);
_focused_window->SetDirty();
} else if (this->viewport->zoom >= ZOOM_LVL_DRAW_MAP) {
this->viewport->map_type = ChangeRenderMode(this->viewport, false);
this->SetDirty();
}
break;
default: return ES_NOT_HANDLED;
}
return ES_HANDLED;
@ -439,7 +461,11 @@ struct MainWindow : Window
virtual void OnMouseWheel(int wheel)
{
if (_settings_client.gui.scrollwheel_scrolling == 0) {
if (_ctrl_pressed) {
/* Cycle through the drawing modes */
this->viewport->map_type = ChangeRenderMode(this->viewport, wheel < 0);
this->SetDirty();
} else if (_settings_client.gui.scrollwheel_scrolling == 0) {
ZoomInOrOutToCursorWindow(wheel < 0, this);
}
}
@ -465,6 +491,16 @@ struct MainWindow : Window
InvalidateWindowData(WC_MAIN_TOOLBAR, 0, data, true);
}
virtual void OnMouseOver(Point pt, int widget)
{
if (pt.x != -1 && _game_mode != GM_MENU) {
/* Show tooltip with last month production or town name */
const Point p = GetTileBelowCursor();
const TileIndex tile = TileVirtXY(p.x, p.y);
if (tile < MapSize()) ShowTooltipForTile(this, tile);
}
}
static HotkeyList hotkeys;
};
@ -517,6 +553,8 @@ static Hotkey global_hotkeys[] = {
Hotkey(_ghk_chat_company_keys, "chat_company", GHK_CHAT_COMPANY),
Hotkey(_ghk_chat_server_keys, "chat_server", GHK_CHAT_SERVER),
#endif
Hotkey(WKC_PAGEUP, "previous_map_mode", GHK_CHANGE_MAP_MODE_PREV),
Hotkey(WKC_PAGEDOWN, "next_map_mode", GHK_CHANGE_MAP_MODE_NEXT),
HOTKEY_LIST_END
};
HotkeyList MainWindow::hotkeys("global", global_hotkeys);

@ -643,6 +643,7 @@ struct TooltipsWindow : public Window
byte paramcount; ///< Number of string parameters in #string_id.
uint64 params[5]; ///< The string parameters.
TooltipCloseCondition close_cond; ///< Condition for closing the window.
char buffer[DRAW_STRING_BUFFER]; ///< Text to draw
TooltipsWindow(Window *parent, StringID str, uint paramcount, const uint64 params[], TooltipCloseCondition close_tooltip) : Window(&_tool_tips_desc)
{
@ -653,6 +654,7 @@ struct TooltipsWindow : public Window
memcpy(this->params, params, sizeof(this->params[0]) * paramcount);
this->paramcount = paramcount;
this->close_cond = close_tooltip;
if (this->paramcount == 0) GetString(this->buffer, str, lastof(this->buffer)); // Get the text while params are available
this->InitNested();
@ -698,10 +700,14 @@ struct TooltipsWindow : public Window
GfxFillRect(r.left, r.top, r.right, r.bottom, PC_BLACK);
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_LIGHT_YELLOW);
for (uint arg = 0; arg < this->paramcount; arg++) {
SetDParam(arg, this->params[arg]);
if (this->paramcount == 0) {
DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, this->buffer, TC_FROMSTRING, SA_CENTER);
} else {
for (uint arg = 0; arg < this->paramcount; arg++) {
SetDParam(arg, this->params[arg]);
}
DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, this->string_id, TC_FROMSTRING, SA_CENTER);
}
DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, this->string_id, TC_FROMSTRING, SA_CENTER);
}
virtual void OnMouseLoop()

@ -15,6 +15,7 @@
#include "../../stdafx.h"
#include "../../string_func.h"
#include "../../command_type.h"
#include "packet.h"
@ -32,7 +33,7 @@ Packet::Packet(NetworkSocketHandler *cs)
this->next = NULL;
this->pos = 0; // We start reading from here
this->size = 0;
this->buffer = MallocT<byte>(SEND_MTU);
this->buffer = MallocT<byte>(SHRT_MAX);
}
/**
@ -47,7 +48,7 @@ Packet::Packet(PacketType type)
/* Skip the size so we can write that in before sending the packet */
this->pos = 0;
this->size = sizeof(PacketSize);
this->buffer = MallocT<byte>(SEND_MTU);
this->buffer = MallocT<byte>(SHRT_MAX);
this->buffer[this->size++] = type;
}
@ -99,7 +100,7 @@ void Packet::Send_bool(bool data)
*/
void Packet::Send_uint8(uint8 data)
{
assert(this->size < SEND_MTU - sizeof(data));
assert(this->size < SHRT_MAX - sizeof(data));
this->buffer[this->size++] = data;
}
@ -109,7 +110,7 @@ void Packet::Send_uint8(uint8 data)
*/
void Packet::Send_uint16(uint16 data)
{
assert(this->size < SEND_MTU - sizeof(data));
assert(this->size < SHRT_MAX - sizeof(data));
this->buffer[this->size++] = GB(data, 0, 8);
this->buffer[this->size++] = GB(data, 8, 8);
}
@ -120,7 +121,7 @@ void Packet::Send_uint16(uint16 data)
*/
void Packet::Send_uint32(uint32 data)
{
assert(this->size < SEND_MTU - sizeof(data));
assert(this->size < SHRT_MAX - sizeof(data));
this->buffer[this->size++] = GB(data, 0, 8);
this->buffer[this->size++] = GB(data, 8, 8);
this->buffer[this->size++] = GB(data, 16, 8);
@ -133,7 +134,7 @@ void Packet::Send_uint32(uint32 data)
*/
void Packet::Send_uint64(uint64 data)
{
assert(this->size < SEND_MTU - sizeof(data));
assert(this->size < SHRT_MAX - sizeof(data));
this->buffer[this->size++] = GB(data, 0, 8);
this->buffer[this->size++] = GB(data, 8, 8);
this->buffer[this->size++] = GB(data, 16, 8);
@ -153,10 +154,22 @@ void Packet::Send_string(const char *data)
{
assert(data != NULL);
/* The <= *is* valid due to the fact that we are comparing sizes and not the index. */
assert(this->size + strlen(data) + 1 <= SEND_MTU);
assert(this->size + strlen(data) + 1 <= SHRT_MAX);
while ((this->buffer[this->size++] = *data++) != '\0') {}
}
/**
* Sends a binary data over the network.
* @param data The data to send
*/
void Packet::Send_binary(const char *data, const size_t size)
{
assert(data != NULL);
assert(size < MAX_CMD_TEXT_LENGTH);
memcpy(&this->buffer[this->size], data, size);
this->size += (PacketSize) size;
}
/*
* Receiving commands
@ -311,4 +324,18 @@ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings set
str_validate(bufp, last, settings);
}
/**
* Reads binary data.
* @param buffer The buffer to put the data into.
* @param size The size of the buffer.
*/
void Packet::Recv_binary(char *buffer, size_t size)
{
/* Don't allow reading from a closed socket */
if (cs->HasClientQuit()) return;
memcpy(buffer, &this->buffer[this->pos], size);
this->pos += (PacketSize) size;
}
#endif /* ENABLE_NETWORK */

@ -52,7 +52,7 @@ struct Packet {
PacketSize size;
/** The current read/write position in the packet */
PacketSize pos;
/** The buffer of this packet, of basically variable length up to SEND_MTU. */
/** The buffer of this packet, of basically variable length up to SHRT_MAX. */
byte *buffer;
private:
@ -73,6 +73,7 @@ public:
void Send_uint32(uint32 data);
void Send_uint64(uint64 data);
void Send_string(const char *data);
void Send_binary(const char *data, const size_t size);
/* Reading/receiving of packets */
void ReadRawPacketSize();
@ -85,6 +86,7 @@ public:
uint32 Recv_uint32();
uint64 Recv_uint64();
void Recv_string(char *buffer, size_t size, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
void Recv_binary(char *buffer, size_t size);
};
#endif /* ENABLE_NETWORK */

@ -862,7 +862,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet
* the server will give us a client-id and let us in */
_network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
ShowJoinStatusWindow();
NetworkSendCommand(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company);
NetworkSendCommand(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company, 0);
}
} else {
/* take control over an existing company */

@ -51,6 +51,7 @@ static CommandCallback * const _callback_table[] = {
/* 0x19 */ CcStartStopVehicle,
/* 0x1A */ CcGame,
/* 0x1B */ CcAddVehicleNewGroup,
/* 0x1C */ CcAddPlan,
};
/**
@ -136,8 +137,9 @@ static CommandQueue _local_execution_queue;
* @param callback A callback function to call after the command is finished
* @param text The text to pass
* @param company The company that wants to send the command
* @param binary_length The quantity of binary data in text
*/
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company)
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company, uint32 binary_length)
{
assert((cmd & CMD_FLAGS_MASK) == 0);
@ -149,7 +151,12 @@ void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, Comman
c.cmd = cmd;
c.callback = callback;
strecpy(c.text, (text != NULL) ? text : "", lastof(c.text));
c.binary_length = binary_length;
if (binary_length == 0) {
strecpy(c.text, (text != NULL) ? text : "", lastof(c.text));
} else {
memcpy(c.text, text, binary_length);
}
if (_network_server) {
/* If we are the server, we queue the command in our 'special' queue.
@ -310,7 +317,13 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c
cp->p1 = p->Recv_uint32();
cp->p2 = p->Recv_uint32();
cp->tile = p->Recv_uint32();
p->Recv_string(cp->text, lengthof(cp->text), (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK);
cp->binary_length = p->Recv_uint32();
if (cp->binary_length == 0) {
p->Recv_string(cp->text, lengthof(cp->text), (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK);
} else {
if ((p->pos + (PacketSize) cp->binary_length + /* callback index */ 1) > p->size) return "invalid binary data length";
p->Recv_binary(cp->text, cp->binary_length);
}
byte callback = p->Recv_uint8();
if (callback >= lengthof(_callback_table)) return "invalid callback";
@ -331,7 +344,12 @@ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp)
p->Send_uint32(cp->p1);
p->Send_uint32(cp->p2);
p->Send_uint32(cp->tile);
p->Send_string(cp->text);
p->Send_uint32(cp->binary_length);
if (cp->binary_length == 0) {
p->Send_string(cp->text);
} else {
p->Send_binary(cp->text, cp->binary_length);
}
byte callback = 0;
while (callback < lengthof(_callback_table) && _callback_table[callback] != cp->callback) {

@ -2192,7 +2192,7 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci)
/* ci is NULL when replaying, or for AIs. In neither case there is a client. */
ci->client_playas = c->index;
NetworkUpdateClientInfo(ci->client_id);
NetworkSendCommand(0, 0, 0, CMD_RENAME_PRESIDENT, NULL, ci->client_name, c->index);
NetworkSendCommand(0, 0, 0, CMD_RENAME_PRESIDENT, NULL, ci->client_name, c->index, 0);
}
/* Announce new company on network. */

@ -102,7 +102,7 @@ struct AnimationBase {
}
SetAnimationFrame(tile, frame);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
/**

@ -597,7 +597,7 @@ bool NewHouseTileLoop(TileIndex tile)
}
SetHouseProcessingTime(tile, hs->processing_time);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
return true;
}
@ -632,7 +632,7 @@ static void DoTriggerHouse(TileIndex tile, HouseTrigger trigger, byte base_rando
case HOUSE_TRIGGER_TILE_LOOP_TOP:
if (!first) {
/* The top tile is marked dirty by the usual TileLoop */
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
break;
}
/* Random value of first tile already set. */

@ -336,7 +336,7 @@ static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, I
random_bits &= ~object.reseed[VSG_SCOPE_SELF];
random_bits |= new_random_bits & object.reseed[VSG_SCOPE_SELF];
SetIndustryRandomBits(tile, random_bits);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
reseed_industry |= object.reseed[VSG_SCOPE_PARENT];
}

@ -1030,7 +1030,7 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg
random_bits |= Random() & reseed;
SetStationTileRandomBits(tile, random_bits);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
}
}

@ -124,7 +124,7 @@ void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, u
DirtyCompanyInfrastructureWindows(owner);
}
MakeObject(t, owner, o->index, wc, Random());
MarkTileDirtyByTile(t);
MarkTileDirtyByTile(t, ZOOM_LVL_DRAW_MAP);
}
Object::IncTypeCount(type);
@ -140,7 +140,7 @@ static void IncreaseAnimationStage(TileIndex tile)
TileArea ta = Object::GetByTile(tile)->location;
TILE_AREA_LOOP(t, ta) {
SetAnimationFrame(t, GetAnimationFrame(t) + 1);
MarkTileDirtyByTile(t);
MarkTileDirtyByTile(t, ZOOM_LVL_DRAW_MAP);
}
}

@ -63,6 +63,7 @@
#include "subsidy_func.h"
#include "gfx_layout.h"
#include "viewport_sprite_sorter.h"
#include "smallmap_gui.h"
#include "linkgraph/linkgraphschedule.h"
@ -1178,6 +1179,8 @@ void SwitchToMode(SwitchMode new_mode)
default: NOT_REACHED();
}
SmallMapWindow::RebuildColourIndexIfNecessary();
}

@ -210,7 +210,7 @@ CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1,
/* We need to circumvent the "prevention" from this command being executed
* while the game is paused, so use the internal method. Nor do we want
* this command to get its cost estimated when shift is pressed. */
DoCommandPInternal(ob->tile, 0, user, CMD_CLEAR_ORDER_BACKUP, NULL, NULL, true, false);
DoCommandPInternal(ob->tile, 0, user, CMD_CLEAR_ORDER_BACKUP, NULL, NULL, true, false, 0);
} else {
/* The command came from the game logic, i.e. the clearing of a tile.
* In that case we have no need to actually sync this, just do it. */

@ -617,6 +617,8 @@ private:
order.SetDepotActionType(ODATFB_NEAREST_DEPOT);
DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER));
MarkAllRoutePathsDirty(this->vehicle);
MarkAllRouteStepsDirty(this);
}
/**
@ -702,6 +704,8 @@ private:
/* When networking, move one order lower */
int selected = this->selected_order + (int)_networking;
MarkAllRoutePathsDirty(this->vehicle);
MarkAllRouteStepsDirty(this);
if (DoCommandP(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), CMD_DELETE_ORDER | CMD_MSG(STR_ERROR_CAN_T_DELETE_THIS_ORDER))) {
this->selected_order = selected >= this->vehicle->GetNumOrders() ? -1 : selected;
this->UpdateButtonState();
@ -795,6 +799,13 @@ public:
this->OnInvalidateData(VIWD_MODIFY_ORDERS);
}
~OrdersWindow()
{
if (!FocusWindowById(WC_VEHICLE_VIEW, this->window_number)) {
MarkAllRouteStepsDirty(this);
}
}
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
switch (widget) {
@ -1169,6 +1180,8 @@ public:
order.MakeConditional(order_id);
DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), order.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER));
MarkAllRoutePathsDirty(this->vehicle);
MarkAllRouteStepsDirty(this);
}
ResetObjectToPlace();
break;
@ -1227,7 +1240,7 @@ public:
} else {
const Order *o = this->vehicle->GetOrder(this->OrderGetSel());
ShowDropDownMenu(this, _order_non_stop_drowdown, o->GetNonStopType(), WID_O_NON_STOP, 0,
o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12));
o->IsType(OT_GOTO_STATION) ? 0 : (o->IsType(OT_GOTO_WAYPOINT) ? 3 : 12), 0, DDSF_LOST_FOCUS);
}
break;
@ -1247,7 +1260,7 @@ public:
case OPOS_SHARE: sel = 3; break;
default: NOT_REACHED();
}
ShowDropDownMenu(this, this->vehicle->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, sel, WID_O_GOTO, 0, 0);
ShowDropDownMenu(this, this->vehicle->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, sel, WID_O_GOTO, 0, 0, 0, DDSF_LOST_FOCUS);
}
break;
@ -1255,7 +1268,7 @@ public:
if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
this->OrderClick_FullLoad(-1);
} else {
ShowDropDownMenu(this, _order_full_load_drowdown, this->vehicle->GetOrder(this->OrderGetSel())->GetLoadType(), WID_O_FULL_LOAD, 0, 2);
ShowDropDownMenu(this, _order_full_load_drowdown, this->vehicle->GetOrder(this->OrderGetSel())->GetLoadType(), WID_O_FULL_LOAD, 0, 2, 0, DDSF_LOST_FOCUS);
}
break;
@ -1263,7 +1276,7 @@ public:
if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
this->OrderClick_Unload(-1);
} else {
ShowDropDownMenu(this, _order_unload_drowdown, this->vehicle->GetOrder(this->OrderGetSel())->GetUnloadType(), WID_O_UNLOAD, 0, 8);
ShowDropDownMenu(this, _order_unload_drowdown, this->vehicle->GetOrder(this->OrderGetSel())->GetUnloadType(), WID_O_UNLOAD, 0, 8, 0, DDSF_LOST_FOCUS);
}
break;
@ -1275,7 +1288,7 @@ public:
if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
this->OrderClick_Service(-1);
} else {
ShowDropDownMenu(this, _order_depot_action_dropdown, DepotActionStringIndex(this->vehicle->GetOrder(this->OrderGetSel())), WID_O_SERVICE, 0, 0);
ShowDropDownMenu(this, _order_depot_action_dropdown, DepotActionStringIndex(this->vehicle->GetOrder(this->OrderGetSel())), WID_O_SERVICE, 0, 0, 0, DDSF_LOST_FOCUS);
}
break;
@ -1283,7 +1296,7 @@ public:
if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
this->OrderClick_Refit(0, true);
} else {
ShowDropDownMenu(this, _order_refit_action_dropdown, 0, WID_O_REFIT_DROPDOWN, 0, 0);
ShowDropDownMenu(this, _order_refit_action_dropdown, 0, WID_O_REFIT_DROPDOWN, 0, 0, 0, DDSF_LOST_FOCUS);
}
break;
@ -1302,7 +1315,7 @@ public:
case WID_O_COND_COMPARATOR: {
const Order *o = this->vehicle->GetOrder(this->OrderGetSel());
ShowDropDownMenu(this, _order_conditional_condition, o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0, (o->GetConditionVariable() == OCV_REQUIRES_SERVICE) ? 0x3F : 0xC0);
ShowDropDownMenu(this, _order_conditional_condition, o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0, (o->GetConditionVariable() == OCV_REQUIRES_SERVICE) ? 0x3F : 0xC0, 0, DDSF_LOST_FOCUS);
break;
}
@ -1448,6 +1461,8 @@ public:
if (cmd.IsType(OT_NOTHING)) return;
if (DoCommandP(this->vehicle->tile, this->vehicle->index + (this->OrderGetSel() << 20), cmd.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER))) {
MarkAllRoutePathsDirty(this->vehicle);
MarkAllRouteStepsDirty(this);
/* With quick goto the Go To button stays active */
if (!_settings_client.gui.quick_goto) ResetObjectToPlace();
}
@ -1510,6 +1525,27 @@ public:
this->vscroll->SetCapacityFromWidget(this, WID_O_ORDER_LIST);
}
virtual void OnFocus(Window *previously_focused_window)
{
if (HasFocusedVehicleChanged(this->window_number, previously_focused_window)) {
MarkAllRoutePathsDirty(this->vehicle);
MarkAllRouteStepsDirty(this);
}
}
virtual void OnFocusLost(Window *newly_focused_window)
{
if (HasFocusedVehicleChanged(this->window_number, newly_focused_window)) {
MarkAllRoutePathsDirty(this->vehicle);
MarkAllRouteStepsDirty(this);
}
}
const Vehicle *GetVehicle()
{
return this->vehicle;
}
static HotkeyList hotkeys;
};

@ -206,7 +206,7 @@ struct OskWindow : public Window {
this->parent->SetWidgetDirty(this->text_btn);
}
virtual void OnFocusLost()
virtual void OnFocusLost(Window *newly_focused_window)
{
VideoDriver::GetInstance()->EditBoxLostFocus();
delete this;

@ -281,14 +281,14 @@ static void NPFMarkTile(TileIndex tile)
/* DEBUG: mark visited tiles by mowing the grass under them ;-) */
if (!IsRailDepot(tile)) {
SetRailGroundType(tile, RAIL_GROUND_BARREN);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
break;
case MP_ROAD:
if (!IsRoadDepot(tile)) {
SetRoadside(tile, ROADSIDE_BARREN);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
break;

@ -82,7 +82,7 @@ private:
do {
if (HasStationReservation(tile)) return false;
SetRailStationReservation(tile, true);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
tile = TILE_ADD(tile, diff);
} while (IsCompatibleTrainStationTile(tile, start) && tile != m_origin_tile);

@ -66,7 +66,7 @@ void SetRailStationPlatformReservation(TileIndex start, DiagDirection dir, bool
do {
SetRailStationReservation(tile, b);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
tile = TILE_ADD(tile, diff);
} while (IsCompatibleTrainStationTile(tile, start));
}
@ -85,7 +85,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations)
if (_settings_client.gui.show_track_reservation) {
/* show the reserved rail if needed */
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
switch (GetTileType(tile)) {
@ -94,7 +94,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations)
if (IsRailDepot(tile)) {
if (!HasDepotReservation(tile)) {
SetDepotReservation(tile, true);
MarkTileDirtyByTile(tile); // some GRFs change their appearance when tile is reserved
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP); // some GRFs change their appearance when tile is reserved
return true;
}
}
@ -104,7 +104,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations)
if (IsLevelCrossing(tile) && !HasCrossingReservation(tile)) {
SetCrossingReservation(tile, true);
BarCrossing(tile);
MarkTileDirtyByTile(tile); // crossing barred, make tile dirty
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP); // crossing barred, make tile dirty
return true;
}
break;
@ -113,7 +113,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations)
if (HasStationRail(tile) && !HasStationReservation(tile)) {
SetRailStationReservation(tile, true);
if (trigger_stations && IsRailStation(tile)) TriggerStationRandomisation(NULL, tile, SRT_PATH_RESERVATION);
MarkTileDirtyByTile(tile); // some GRFs need redraw after reserving track
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP); // some GRFs need redraw after reserving track
return true;
}
break;
@ -141,14 +141,14 @@ void UnreserveRailTrack(TileIndex tile, Track t)
assert((GetTileTrackStatus(tile, TRANSPORT_RAIL, 0) & TrackToTrackBits(t)) != 0);
if (_settings_client.gui.show_track_reservation) {
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
switch (GetTileType(tile)) {
case MP_RAILWAY:
if (IsRailDepot(tile)) {
SetDepotReservation(tile, false);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
break;
}
if (IsPlainRail(tile)) UnreserveTrack(tile, t);
@ -164,7 +164,7 @@ void UnreserveRailTrack(TileIndex tile, Track t)
case MP_STATION:
if (HasStationRail(tile)) {
SetRailStationReservation(tile, false);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
break;

@ -0,0 +1,21 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file plans.cpp Handling of plans. */
#include "stdafx.h"
#include "plans_base.h"
#include "core/pool_func.hpp"
/** Initialize the plan-pool */
PlanPool _plan_pool("Plan");
INSTANTIATE_POOL_METHODS(Plan)
Plan *_current_plan = NULL;
Plan *_new_plan = NULL;

@ -0,0 +1,237 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file plans_base.h Base class for plans. */
#ifndef PLANS_BASE_H
#define PLANS_BASE_H
#include "plans_func.h"
#include "core/pool_type.hpp"
#include "company_type.h"
#include "company_func.h"
#include "command_func.h"
#include "map_func.h"
#include "date_func.h"
#include "viewport_func.h"
#include "core/endian_func.hpp"
#include <vector>
typedef Pool<Plan, PlanID, 16, 64000> PlanPool;
typedef std::vector<TileIndex> TileVector;
typedef std::vector<PlanLine*> PlanLineVector;
extern PlanPool _plan_pool;
struct PlanLine {
bool visible;
bool focused;
TileVector tiles;
PlanLine()
{
this->visible = true;
this->focused = false;
}
~PlanLine()
{
this->Clear();
}
void Clear()
{
this->tiles.clear();
}
bool AppendTile(TileIndex tile)
{
const uint cnt = (uint) this->tiles.size();
if (cnt > 0) {
const TileIndex last_tile = this->tiles[cnt - 1];
if (last_tile == tile) return false;
MarkTileLineDirty(last_tile, tile);
if (cnt > 1) {
const TileIndex t0 = this->tiles[cnt - 2];
const int x0 = (int) TileX(t0);
const int y0 = (int) TileY(t0);
const TileIndex t1 = this->tiles[cnt - 1];
const int x1 = (int) TileX(t1);
const int y1 = (int) TileY(t1);
const int x2 = (int) TileX(tile);
const int y2 = (int) TileY(tile);
if ((y1 - y0) * (x2 - x1) == (y2 - y1) * (x1 - x0)) { // Same direction.
if (abs(x2 - x1) <= abs(x2 - x0) && abs(y2 - y1) <= abs(y2 - y0)) { // Tile i+1 is between i and i+2.
/* The new tile is in the continuity, just update the last tile. */
this->tiles[cnt - 1] = tile;
MarkTileLineDirty(t1, tile);
return true;
}
}
}
}
if (this->tiles.size() * sizeof(TileIndex) >= MAX_CMD_TEXT_LENGTH) return false;
this->tiles.push_back(tile);
return true;
}
void SetFocus(bool focused)
{
if (this->focused != focused) this->MarkDirty();
this->focused = focused;
}
bool ToggleVisibility()
{
this->SetVisibility(!this->visible);
return this->visible;
}
void SetVisibility(bool visible)
{
if (this->visible != visible) this->MarkDirty();
this->visible = visible;
}
void MarkDirty()
{
const uint sz = (uint) this->tiles.size();
for (uint i = 1; i < sz; i++) {
MarkTileLineDirty(this->tiles[i-1], this->tiles[i]);
}
}
TileIndex *Export(uint *buffer_length)
{
const uint cnt = (uint) this->tiles.size();
const uint datalen = sizeof(TileIndex) * cnt;
TileIndex *buffer = (TileIndex *) malloc(datalen);
if (buffer) {
for (uint i = 0; i < cnt; i++) {
buffer[i] = TO_LE32(this->tiles[i]);
}
if (buffer_length) *buffer_length = datalen;
}
return buffer;
}
void Import(const TileIndex* data, const uint data_length)
{
for (uint i = data_length; i != 0; i--, data++) {
this->tiles.push_back(FROM_LE32(*data));
}
}
};
struct Plan : PlanPool::PoolItem<&_plan_pool> {
OwnerByte owner;
PlanLineVector lines;
PlanLine *temp_line;
bool visible;
bool visible_by_all;
bool show_lines;
Date creation_date;
Plan(Owner owner = INVALID_OWNER)
{
this->owner = owner;
this->creation_date = _date;
this->visible = false;
this->visible_by_all = false;
this->show_lines = false;
this->temp_line = new PlanLine();
}
~Plan()
{
for (PlanLineVector::iterator it = lines.begin(); it != lines.end(); it++) {
delete (*it);
}
this->lines.clear();
delete temp_line;
}
void SetFocus(bool focused)
{
for (PlanLineVector::iterator it = lines.begin(); it != lines.end(); it++) {
(*it)->SetFocus(focused);
}
}
void SetVisibility(bool visible, bool do_lines = true)
{
this->visible = visible;
if (!do_lines) return;
for (PlanLineVector::iterator it = lines.begin(); it != lines.end(); it++) {
(*it)->SetVisibility(visible);
}
}
bool ToggleVisibility()
{
this->SetVisibility(!this->visible);
return this->visible;
}
PlanLine *NewLine()
{
PlanLine *pl = new PlanLine();
if (pl) this->lines.push_back(pl);
return pl;
}
bool StoreTempTile(TileIndex tile)
{
return this->temp_line->AppendTile(tile);
}
bool ValidateNewLine()
{
bool ret = false;
if (this->temp_line->tiles.size() > 1) {
uint buffer_length = 0;
const TileIndex *buffer = this->temp_line->Export(&buffer_length);
if (buffer) {
_current_plan->SetVisibility(true, false);
ret = DoCommandP(0, _current_plan->index, (uint32) this->temp_line->tiles.size(), CMD_ADD_PLAN_LINE, NULL, (const char *) buffer, true, buffer_length);
free(buffer);
}
_current_plan->temp_line->MarkDirty();
this->temp_line->Clear();
}
return ret;
}
bool IsListable()
{
return (this->owner == _local_company || this->visible_by_all);
}
bool IsVisible()
{
if (!this->IsListable()) return false;
return this->visible;
}
bool ToggleVisibilityByAll()
{
if (_current_plan->owner == _local_company) DoCommandP(0, _current_plan->index, !this->visible_by_all, CMD_CHANGE_PLAN_VISIBILITY);
return this->visible_by_all;
}
};
#define FOR_ALL_PLANS_FROM(var, start) FOR_ALL_ITEMS_FROM(Plan, plan_index, var, start)
#define FOR_ALL_PLANS(var) FOR_ALL_PLANS_FROM(var, 0)
#endif /* PLANS_BASE_H */

@ -0,0 +1,140 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file plans_cmd.cpp Handling of plan related commands. */
#include "stdafx.h"
#include "command_func.h"
#include "plans_base.h"
#include "plans_func.h"
#include "window_func.h"
#include "company_func.h"
#include "window_gui.h"
#include "table/strings.h"
/**
* Create a new plan.
* @param tile unused
* @param flags type of operation
* @param p1 owner of the plan
* @param p2 unused
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdAddPlan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (!Plan::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_PLANS);
if (flags & DC_EXEC) {
Owner o = (Owner) p1;
_new_plan = new Plan(o);
if (o == _local_company) {
_new_plan->SetVisibility(true);
Window *w = FindWindowById(WC_PLANS, 0);
if (w) w->InvalidateData(INVALID_PLAN, false);
}
}
return CommandCost();
}
/**
* Create a new line in a plan.
* @param tile unused
* @param flags type of operation
* @param p1 plan id
* @param p2 number of nodes
* @param text list of tile indexes that compose the line, encoded in base64
* @return the cost of this operation or an error
*/
CommandCost CmdAddPlanLine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (flags & DC_EXEC) {
Plan *p = Plan::Get(p1);
PlanLine *pl = p->NewLine();
if (!pl) return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_LINES);
if (p2 > (MAX_CMD_TEXT_LENGTH / sizeof(TileIndex))) return_cmd_error(STR_ERROR_TOO_MANY_NODES);
pl->Import((const TileIndex *) text, p2);
if (p->IsListable()) {
pl->SetVisibility(p->visible);
if (p->visible) pl->MarkDirty();
Window *w = FindWindowById(WC_PLANS, 0);
if (w) w->InvalidateData(INVALID_PLAN, false);
}
}
return CommandCost();
}
/**
* Edit the visibility of a plan.
* @param tile unused
* @param flags type of operation
* @param p1 plan id
* @param p2 visibility
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdChangePlanVisibility(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (flags & DC_EXEC) {
Plan *p = Plan::Get(p1);
p->visible_by_all = p2 != 0;
Window *w = FindWindowById(WC_PLANS, 0);
if (w) w->InvalidateData(INVALID_PLAN, false);
}
return CommandCost();
}
/**
* Delete a plan.
* @param tile unused
* @param flags type of operation
* @param p1 plan id
* @param p2 unused
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdRemovePlan(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (flags & DC_EXEC) {
Plan *p = Plan::Get(p1);
if (p->IsListable()) {
p->SetVisibility(false);
Window *w = FindWindowById(WC_PLANS, 0);
if (w) w->InvalidateData(p->index, false);
}
if (p == _current_plan) _current_plan = NULL;
delete p;
}
return CommandCost();
}
/**
* Remove a line from a plan.
* @param tile unused
* @param flags type of operation
* @param p1 plan id
* @param p2 line id
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdRemovePlanLine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
if (flags & DC_EXEC) {
Plan *p = Plan::Get(p1);
PlanLineVector::iterator it = p->lines.begin();
std::advance(it, p2);
(*it)->SetVisibility(false);
delete *it;
p->lines.erase(it);
if (p->IsListable()) {
Window *w = FindWindowById(WC_PLANS, 0);
if (w) w->InvalidateData(p->index, false);
}
}
return CommandCost();
}

@ -0,0 +1,22 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file plans_func.h Functions related to plans. */
#ifndef PLANS_FUNC_H
#define PLANS_FUNC_H
#include "plans_type.h"
void ShowPlansWindow();
extern Plan *_new_plan;
extern Plan *_current_plan;
#endif /* PLANS_FUNC_H */

@ -0,0 +1,366 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file plans_gui.cpp The GUI for planning. */
#include "stdafx.h"
#include "plans_func.h"
#include "plans_base.h"
#include "command_func.h"
#include "company_func.h"
#include "company_gui.h"
#include "settings_gui.h"
#include "window_gui.h"
#include "window_func.h"
#include "viewport_func.h"
#include "gfx_func.h"
#include "tilehighlight_func.h"
#include "strings_func.h"
#include "core/pool_func.hpp"
#include "widgets/plans_widget.h"
#include "table/strings.h"
#include "table/sprites.h"
static const NWidgetPart _nested_plans_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_GREY),
NWidget(WWT_CAPTION, COLOUR_GREY, WID_PLN_CAPTION), SetDataTip(STR_PLANS_CAPTION, STR_NULL),
NWidget(WWT_SHADEBOX, COLOUR_GREY),
NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_INSET, COLOUR_GREY, WID_PLN_LIST), SetFill(1, 1), SetPadding(2, 1, 2, 2), SetResize(1, 0), SetScrollbar(WID_PLN_SCROLLBAR), SetDataTip(STR_NULL, STR_PLANS_LIST_TOOLTIP),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_PLN_SCROLLBAR),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_PLN_NEW), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_PLANS_NEW_PLAN, STR_NULL),
NWidget(WWT_TEXTBTN_2, COLOUR_GREY, WID_PLN_ADD_LINES), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_PLANS_ADD_LINES, STR_PLANS_ADDING_LINES),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_PLN_VISIBILITY), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_PLANS_VISIBILITY_PUBLIC, STR_PLANS_VISIBILITY_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_PLN_HIDE_ALL), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_PLANS_HIDE_ALL, STR_NULL),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_PLN_DELETE), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_PLANS_DELETE, STR_PLANS_DELETE_TOOLTIP),
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
EndContainer(),
EndContainer(),
};
static WindowDesc _plans_desc(
WDP_AUTO, "plans", 300, 100,
WC_PLANS, WC_NONE,
WDF_CONSTRUCTION,
_nested_plans_widgets, lengthof(_nested_plans_widgets)
);
struct PlansWindow : Window {
typedef struct {
bool is_plan;
int plan_id;
int line_id;
} ListItem;
Scrollbar *vscroll;
int text_offset;
std::vector<ListItem> list; ///< The translation table linking panel indices to their related PlanID.
int selected; ///< What item is currently selected in the panel.
PlansWindow(WindowDesc *desc) : Window(desc)
{
this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_PLN_SCROLLBAR);
this->FinishInitNested();
Dimension spr_dim = GetSpriteSize(SPR_COMPANY_ICON);
this->text_offset = WD_FRAMETEXT_LEFT + spr_dim.width + 2 + SETTING_BUTTON_WIDTH;
this->selected = INT_MAX;
RebuildList();
}
~PlansWindow()
{
this->list.clear();
_current_plan = NULL;
}
virtual void OnClick(Point pt, int widget, int click_count)
{
switch (widget) {
case WID_PLN_NEW:
DoCommandP(0, _local_company, 0, CMD_ADD_PLAN, CcAddPlan);
break;
case WID_PLN_ADD_LINES:
if (_current_plan) HandlePlacePushButton(this, widget, SPR_CURSOR_MOUSE, HT_POINT);
break;
case WID_PLN_DELETE:
if (this->selected != INT_MAX) {
if (this->list[this->selected].is_plan) {
DoCommandP(0, this->list[this->selected].plan_id, 0, CMD_REMOVE_PLAN);
} else {
DoCommandP(0, this->list[this->selected].plan_id, this->list[this->selected].line_id, CMD_REMOVE_PLAN_LINE);
}
}
break;
case WID_PLN_HIDE_ALL: {
Plan *p;
FOR_ALL_PLANS(p) {
if (p->IsListable()) p->SetVisibility(false);
}
this->SetWidgetDirty(WID_PLN_LIST);
break;
}
case WID_PLN_VISIBILITY:
if (_current_plan) _current_plan->ToggleVisibilityByAll();
break;
case WID_PLN_LIST: {
int new_selected = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_PLN_LIST, WD_FRAMERECT_TOP);
if (this->selected != INT_MAX) {
_current_plan->SetFocus(false);
}
if (new_selected != INT_MAX) {
if (this->list[new_selected].is_plan) {
_current_plan = Plan::Get(this->list[new_selected].plan_id);
_current_plan->SetFocus(true);
if (pt.x >= 22 && pt.x < 41) _current_plan->ToggleVisibility();
} else {
_current_plan = Plan::Get(this->list[new_selected].plan_id);
PlanLine *pl = _current_plan->lines[this->list[new_selected].line_id];
pl->SetFocus(true);
if (pt.x >= 22 && pt.x < 41) {
if (pl->ToggleVisibility()) _current_plan->SetVisibility(true, false);
}
}
if (click_count > 1 && (pt.x < 22 || pt.x >= 41)) {
_current_plan->show_lines = !_current_plan->show_lines;
this->InvalidateData(INVALID_PLAN);
}
} else {
if (_current_plan) {
_current_plan->SetFocus(false);
_current_plan = NULL;
}
}
this->selected = new_selected;
this->SetDirty();
break;
}
default: break;
}
}
virtual void OnPaint()
{
this->SetWidgetDisabledState(WID_PLN_HIDE_ALL, this->vscroll->GetCount() == 0);
if (_current_plan) {
this->SetWidgetsDisabledState(_current_plan->owner != _local_company, WID_PLN_ADD_LINES, WID_PLN_VISIBILITY, WID_PLN_DELETE, WIDGET_LIST_END);
this->GetWidget<NWidgetCore>(WID_PLN_VISIBILITY)->widget_data = _current_plan->visible_by_all ? STR_PLANS_VISIBILITY_PRIVATE : STR_PLANS_VISIBILITY_PUBLIC;
} else {
this->SetWidgetsDisabledState(true, WID_PLN_ADD_LINES, WID_PLN_VISIBILITY, WID_PLN_DELETE, WIDGET_LIST_END);
}
this->DrawWidgets();
}
virtual void DrawWidget(const Rect &r, int widget) const
{
switch (widget) {
case WID_PLN_LIST: {
uint y = r.top + WD_FRAMERECT_TOP; // Offset from top of widget.
if (this->vscroll->GetCount() == 0) {
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_STATION_LIST_NONE);
return;
}
bool rtl = _current_text_dir == TD_RTL;
uint icon_left = 4 + (rtl ? r.right - this->text_offset : r.left);
uint btn_left = (rtl ? icon_left - SETTING_BUTTON_WIDTH + 4 : icon_left + SETTING_BUTTON_WIDTH - 4);
uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : this->text_offset);
uint text_right = r.right - (rtl ? this->text_offset : WD_FRAMERECT_RIGHT);
for (uint16 i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) {
Plan *p = Plan::Get(list[i].plan_id);
if (i == this->selected) GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, PC_DARK_GREY);
if (list[i].is_plan) {
DrawCompanyIcon(p->owner, icon_left, y + (FONT_HEIGHT_NORMAL - 10) / 2 + 1);
DrawBoolButton(btn_left, y + (FONT_HEIGHT_NORMAL - 10) / 2, p->visible, true);
SetDParam(0, list[i].plan_id + 1);
SetDParam(1, p->lines.size());
SetDParam(2, p->creation_date);
DrawString(text_left, text_right, y, STR_PLANS_LIST_ITEM_PLAN, p->visible_by_all ? TC_LIGHT_BLUE : TC_YELLOW);
} else {
PlanLine *pl = p->lines[list[i].line_id];
DrawBoolButton(btn_left, y + (FONT_HEIGHT_NORMAL - 10) / 2, pl->visible, true);
SetDParam(0, list[i].line_id + 1);
SetDParam(1, pl->tiles.size() - 1);
DrawString(text_left, text_right, y, STR_PLANS_LIST_ITEM_LINE, TC_WHITE);
}
y += this->resize.step_height;
}
break;
}
}
}
virtual void OnResize()
{
this->vscroll->SetCapacityFromWidget(this, WID_PLN_LIST, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM);
}
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
switch (widget) {
case WID_PLN_LIST:
resize->height = FONT_HEIGHT_NORMAL;
size->height = resize->height * 5 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
break;
}
}
/** The drawing of a line starts. */
virtual void OnPlaceObject(Point pt, TileIndex tile)
{
/* A player can't add lines to a public plan of another company. */
if (_current_plan && _current_plan->owner == _local_company) VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_DRAW_PLANLINE);
}
/** The drawing of a line is in progress. */
virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt)
{
const Point p = GetTileBelowCursor();
const TileIndex tile = TileVirtXY(p.x, p.y);
if (_current_plan && tile < MapSize()) {
_current_plan->StoreTempTile(tile);
_thd.selstart = _thd.selend;
}
}
/** The drawing of a line ends up normally. */
virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile)
{
if (_current_plan) _current_plan->ValidateNewLine();
}
/** The drawing of a line is aborted. */
virtual void OnPlaceObjectAbort()
{
if (_current_plan) {
_current_plan->temp_line->MarkDirty();
_current_plan->temp_line->Clear();
}
this->RaiseWidget(WID_PLN_ADD_LINES);
this->SetWidgetDirty(WID_PLN_ADD_LINES);
}
void RebuildList()
{
int old_focused_plan_id = this->selected == INT_MAX ? INT_MAX : this->list[this->selected].plan_id;
int sbcnt = 0;
this->list.clear();
Plan *p;
FOR_ALL_PLANS(p) {
if (!p->IsListable()) continue;
ListItem li;
li.is_plan = true;
li.plan_id = p->index;
this->list.push_back(li);
if (old_focused_plan_id == p->index) this->selected = sbcnt;
sbcnt++;
if (p->show_lines) {
const int sz = (int) p->lines.size();
sbcnt += sz;
li.is_plan = false;
for (int i = 0; i < sz; i++) {
li.line_id = i;
this->list.push_back(li);
}
}
}
if (this->selected == INT_MAX) ResetObjectToPlace();
this->vscroll->SetCount(sbcnt);
}
virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
{
if (data != INVALID_PLAN && this->selected != INT_MAX) {
if (this->list[this->selected].plan_id == data) {
/* Invalidate the selection if the selected plan has been modified or deleted. */
this->selected = INT_MAX;
/* Cancel drawing associated to the deleted plan. */
ResetObjectToPlace();
}
}
RebuildList();
}
void SelectPlan(PlanID plan_index)
{
if (this->selected != INT_MAX) {
if (plan_index == this->list[this->selected].plan_id) return;
Plan::Get(this->list[this->selected].plan_id)->SetFocus(false);
}
if (plan_index == INVALID_PLAN) {
this->selected = INT_MAX;
return;
}
Plan::Get(plan_index)->SetFocus(true);
for (size_t i = 0; i < this->list.size(); i++) {
if (this->list[i].is_plan && this->list[i].plan_id == plan_index) {
this->selected = (int) i;
return;
}
}
}
};
/** Show the window to manage plans. */
void ShowPlansWindow()
{
if (BringWindowToFrontById(WC_PLANS, 0) != NULL) return;
new PlansWindow(&_plans_desc);
}
/**
* Only the creator of a plan executes this function.
* The other players should not be bothered with these changes.
*/
void CcAddPlan(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
{
if (result.Failed()) return;
_current_plan = _new_plan;
_current_plan->SetVisibility(true);
Window *w = FindWindowById(WC_PLANS, 0);
if (w) {
w->InvalidateData(INVALID_PLAN, false);
((PlansWindow *) w)->SelectPlan(_current_plan->index);
if (!w->IsWidgetLowered(WID_PLN_ADD_LINES)) {
w->SetWidgetDisabledState(WID_PLN_ADD_LINES, false);
HandlePlacePushButton(w, WID_PLN_ADD_LINES, SPR_CURSOR_MOUSE, HT_POINT);
}
}
}

@ -0,0 +1,25 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file plans_type.h Types related to planning. */
#ifndef PLANS_TYPE_H
#define PLANS_TYPE_H
#include "stdafx.h"
#include "core/smallvec_type.hpp"
#include "tile_type.h"
typedef uint16 PlanID;
struct PlanLine;
struct Plan;
static const PlanID INVALID_PLAN = 0xFFFF; ///< Sentinel for an invalid plan.
#endif /* PLANS_TYPE_H */

@ -1137,7 +1137,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
uint mask = GetPresentSignals(tile) & SignalOnTrack(track);
SetSignalStates(tile, (GetSignalStates(tile) & ~mask) | ((HasBit(GetRailReservationTrackBits(tile), track) && EnsureNoVehicleOnGround(tile).Succeeded() ? UINT_MAX : 0) & mask));
}
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
AddTrackToSignalBuffer(tile, track, _current_company);
YapfNotifyTrackLayoutChange(tile, track);
if (v != NULL) {
@ -1462,7 +1462,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1
YapfNotifyTrackLayoutChange(tile, track);
if (v != NULL) TryPathReserve(v, false);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_SIGNALS]);
@ -1605,7 +1605,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
}
SetRailType(tile, totype);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
/* update power of train on this tile */
FindVehicleOnPos(tile, &affected_trains, &UpdateTrainPowerProc);
}
@ -1688,13 +1688,13 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
YapfNotifyTrackLayoutChange(tile, track);
YapfNotifyTrackLayoutChange(endtile, track);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(endtile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
MarkTileDirtyByTile(endtile, ZOOM_LVL_DRAW_MAP);
if (IsBridge(tile)) {
TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
TileIndex t = tile + delta;
for (; t != endtile; t += delta) MarkTileDirtyByTile(t); // TODO encapsulate this into a function
for (; t != endtile; t += delta) MarkTileDirtyByTile(t, ZOOM_LVL_DRAW_MAP); // TODO encapsulate this into a function
}
}

@ -198,7 +198,7 @@ static void PlaceRail_Station(TileIndex tile)
int h = _settings_client.gui.station_platlength;
if (!_railstation.orientation) Swap(w, h);
CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
CommandContainer cmdcont = { tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, 0, "" };
ShowSelectStationIfNeeded(cmdcont, TileArea(tile, w, h));
}
}
@ -719,7 +719,7 @@ struct BuildRailToolbarWindow : Window {
uint32 p1 = _cur_railtype | (select_method == VPM_FIX_X ? AXIS_X : AXIS_Y) << 4 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24;
uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16;
CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT), CcPlaySound1E, "" };
CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT), CcPlaySound1E, 0, "" };
ShowSelectWaypointIfNeeded(cmdcont, ta);
}
}
@ -876,7 +876,7 @@ static void HandleStationPlacement(TileIndex start, TileIndex end)
uint32 p1 = _cur_railtype | _railstation.orientation << 4 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24;
uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;
CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, 0, "" };
ShowSelectStationIfNeeded(cmdcont, ta);
}

@ -1522,7 +1522,7 @@ static void TileLoop_Road(TileIndex tile)
TileY(tile) * TILE_SIZE + 7,
0,
EV_BULLDOZER);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
return;
}
}
@ -1547,7 +1547,7 @@ static void TileLoop_Road(TileIndex tile)
cur_rs = ROADSIDE_BARREN;
}
SetRoadside(tile, cur_rs);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
} else if (IncreaseRoadWorksCounter(tile)) {
TerminateRoadWorks(tile);
@ -1562,7 +1562,7 @@ static void TileLoop_Road(TileIndex tile)
}
}
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
}

@ -233,7 +233,7 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, u
p2 |= ddir << 6; // Set the DiagDirecion into p2 bits 6 and 7.
TileArea ta(start_tile, end_tile);
CommandContainer cmdcont = { ta.tile, ta.w | ta.h << 8, p2, cmd, CcRoadStop, "" };
CommandContainer cmdcont = { ta.tile, ta.w | ta.h << 8, p2, cmd, CcRoadStop, 0, "" };
ShowSelectStationIfNeeded(cmdcont, ta);
}

@ -0,0 +1,87 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file plans_sl.cpp Code handling saving and loading of plans data. */
#include "../stdafx.h"
#include "../plans_base.h"
#include "../fios.h"
#include "saveload.h"
/** Description of a plan within the savegame. */
static const SaveLoad _plan_desc[] = {
SLE_VAR(Plan, owner, SLE_UINT8),
SLE_VAR(Plan, visible, SLE_BOOL),
SLE_VAR(Plan, visible_by_all, SLE_BOOL),
SLE_VAR(Plan, creation_date, SLE_INT32),
SLE_END()
};
/** Save all plans. */
static void Save_PLAN()
{
Plan *p;
FOR_ALL_PLANS(p) {
SlSetArrayIndex(p->index);
SlObject(p, _plan_desc);
}
}
/** Load all plans. */
static void Load_PLAN()
{
int index;
while ((index = SlIterateArray()) != -1) {
Plan *p = new (index) Plan();
SlObject(p, _plan_desc);
}
}
/** Save all plan lines. */
static void Save_PLANLINE()
{
Plan *p;
FOR_ALL_PLANS(p) {
for (size_t i = 0; i < p->lines.size(); i++) {
SlSetArrayIndex((uint) p->index << 16 | (uint) i);
PlanLine *pl = p->lines[i];
size_t plsz = pl->tiles.size();
SlSetLength(plsz * sizeof(TileIndex));
SlArray(&pl->tiles[0], plsz, SLE_UINT32);
}
}
}
/** Load all plan lines. */
static void Load_PLANLINE()
{
int index;
while ((index = SlIterateArray()) != -1) {
Plan *p = Plan::Get((uint) index >> 16);
uint line_index = index & 0xFFFF;
if (p->lines.size() <= line_index) p->lines.resize(line_index + 1);
PlanLine *pl = new PlanLine();
p->lines[line_index] = pl;
size_t plsz = SlGetFieldLength() / sizeof(TileIndex);
pl->tiles.resize(plsz);
SlArray(&pl->tiles[0], plsz, SLE_UINT32);
}
Plan *p;
FOR_ALL_PLANS(p) {
p->SetVisibility(false);
}
}
/** Chunk handlers related to plans. */
extern const ChunkHandler _plan_chunk_handlers[] = {
{ 'PLAN', Save_PLAN, Load_PLAN, NULL, NULL, CH_ARRAY},
{ 'PLLN', Save_PLANLINE, Load_PLANLINE, NULL, NULL, CH_ARRAY | CH_LAST},
};

@ -263,7 +263,7 @@
* 193 26802
* 194 26881
*/
extern const uint16 SAVEGAME_VERSION = 194; ///< Current savegame version of OpenTTD.
extern const uint16 SAVEGAME_VERSION = 195; ///< Current savegame version of OpenTTD.
SavegameType _savegame_type; ///< type of savegame we are loading
@ -447,6 +447,7 @@ extern const ChunkHandler _linkgraph_chunk_handlers[];
extern const ChunkHandler _airport_chunk_handlers[];
extern const ChunkHandler _object_chunk_handlers[];
extern const ChunkHandler _persistent_storage_chunk_handlers[];
extern const ChunkHandler _plan_chunk_handlers[];
/** Array of all chunks in a savegame, \c NULL terminated. */
static const ChunkHandler * const _chunk_handlers[] = {
@ -483,6 +484,7 @@ static const ChunkHandler * const _chunk_handlers[] = {
_airport_chunk_handlers,
_object_chunk_handlers,
_persistent_storage_chunk_handlers,
_plan_chunk_handlers,
NULL,
};

@ -307,7 +307,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
#endif
/* Try to perform the command. */
CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : NULL, text, false, estimate_only);
CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : NULL, text, false, estimate_only, 0);
/* We failed; set the error and bail out */
if (res.Failed()) {

@ -1966,7 +1966,7 @@ void SyncCompanySettings()
const void *new_var = GetVariableAddress(&_settings_client.company, &sd->save);
uint32 old_value = (uint32)ReadValue(old_var, sd->save.conv);
uint32 new_value = (uint32)ReadValue(new_var, sd->save.conv);
if (old_value != new_value) NetworkSendCommand(0, i, new_value, CMD_CHANGE_COMPANY_SETTING, NULL, NULL, _local_company);
if (old_value != new_value) NetworkSendCommand(0, i, new_value, CMD_CHANGE_COMPANY_SETTING, NULL, NULL, _local_company, 0);
}
}
#endif /* ENABLE_NETWORK */

@ -1256,7 +1256,6 @@ uint SettingsContainer::GetMaxHelpHeight(int maxw)
return biggest;
}
/**
* Draw a row in the settings panel.
*
@ -1478,6 +1477,9 @@ static SettingsContainer &GetSettingsTree()
graphics->Add(new SettingEntry("gui.zoom_max"));
graphics->Add(new SettingEntry("gui.smallmap_land_colour"));
graphics->Add(new SettingEntry("gui.graph_line_thickness"));
graphics->Add(new SettingEntry("gui.show_vehicle_route_steps"));
graphics->Add(new SettingEntry("gui.show_vehicle_route"));
graphics->Add(new SettingEntry("gui.dash_level_of_route_lines"));
}
SettingsPage *sound = main->Add(new SettingsPage(STR_CONFIG_SETTING_SOUND));
@ -1505,6 +1507,18 @@ static SettingsContainer &GetSettingsTree()
SettingsPage *viewports = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_VIEWPORTS));
{
SettingsPage *viewport_map = interface->Add(new SettingsPage(STR_CONFIG_SETTING_VIEWPORT_MAP_OPTIONS));
{
viewport_map->Add(new SettingEntry("gui.default_viewport_map_mode"));
viewport_map->Add(new SettingEntry("gui.action_when_viewport_map_is_dblclicked"));
viewport_map->Add(new SettingEntry("gui.viewport_map_scan_surroundings"));
viewport_map->Add(new SettingEntry("gui.show_scrolling_viewport_on_map"));
viewport_map->Add(new SettingEntry("gui.show_slopes_on_viewport_map"));
viewport_map->Add(new SettingEntry("gui.show_bridges_on_map"));
viewport_map->Add(new SettingEntry("gui.show_tunnels_on_map"));
viewport_map->Add(new SettingEntry("gui.use_owner_colour_for_tunnelbridge"));
}
viewports->Add(new SettingEntry("gui.auto_scrolling"));
viewports->Add(new SettingEntry("gui.reverse_scroll"));
viewports->Add(new SettingEntry("gui.smooth_scroll"));

@ -111,6 +111,16 @@ struct GUISettings {
uint8 right_mouse_btn_emulation; ///< should we emulate right mouse clicking?
uint8 scrollwheel_scrolling; ///< scrolling using the scroll wheel?
uint8 scrollwheel_multiplier; ///< how much 'wheel' per incoming event from the OS?
bool viewport_map_scan_surroundings; ///< look for the most important tile in surroundings
bool show_slopes_on_viewport_map; ///< use slope orientation to render the ground
uint32 default_viewport_map_mode; ///< the mode to use by default when a viewport is in map mode, 0=owner, 1=industry, 2=vegetation
uint32 action_when_viewport_map_is_dblclicked; ///< what to do when a doubleclick occurs on the viewport map
uint32 show_scrolling_viewport_on_map; ///< when a no map viewport is scrolled, its location is marked on the other map viewports
bool show_bridges_on_map; ///< bridges are rendered on a viewport in map mode
bool show_tunnels_on_map; ///< tunnels are rendered on a viewport in map mode
uint32 show_vehicle_route; ///< show a vehicle's route when its orders/timetable window is focused
uint32 dash_level_of_route_lines; ///< the dash level passed to GfxDrawLine() (plain if 0)
bool use_owner_colour_for_tunnelbridge;///< bridges and tunnels are rendered with their owner's colour
bool timetable_arrival_departure; ///< show arrivals and departures in vehicle timetables
bool left_mouse_btn_scrolling; ///< left mouse button scroll
bool pause_on_newgame; ///< whether to start new games paused or not
@ -136,6 +146,7 @@ struct GUISettings {
byte missing_strings_threshold; ///< the number of missing strings before showing the warning
uint8 graph_line_thickness; ///< the thickness of the lines in the various graph guis
uint8 osk_activation; ///< Mouse gesture to trigger the OSK.
bool show_vehicle_route_steps; ///< when a window related to a specific vehicle is focused, show route steps
uint16 console_backlog_timeout; ///< the minimum amount of time items should be in the console backlog before they will be removed in ~3 seconds granularity.
uint16 console_backlog_length; ///< the minimum amount of items in the console backlog before items will be removed.

@ -446,7 +446,7 @@ static void UpdateSignalsAroundSegment(SigFlags flags)
_globset.Add(tile, exitdir); // do not check for full global set, first update all signals
}
SetSignalStateByTrackdir(tile, trackdir, newstate);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
}

@ -0,0 +1,106 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file smallmap_colours.h Colours used by smallmap. */
#ifndef SMALLMAP_COLOURS_H
#define SMALLMAP_COLOURS_H
#include "core/endian_func.hpp"
static const uint8 PC_ROUGH_LAND = 0x52; ///< Dark green palette colour for rough land.
static const uint8 PC_GRASS_LAND = 0x54; ///< Dark green palette colour for grass land.
static const uint8 PC_BARE_LAND = 0x37; ///< Brown palette colour for bare land.
static const uint8 PC_FIELDS = 0x25; ///< Light brown palette colour for fields.
static const uint8 PC_TREES = 0x57; ///< Green palette colour for trees.
static const uint8 PC_WATER = 0xCA; ///< Dark blue palette colour for water.
#define MKCOLOUR(x) TO_LE32X(x)
#define MKCOLOUR_XXXX(x) (MKCOLOUR(0x01010101) * (uint)(x))
#define MKCOLOUR_X0X0(x) (MKCOLOUR(0x01000100) * (uint)(x))
#define MKCOLOUR_0X0X(x) (MKCOLOUR(0x00010001) * (uint)(x))
#define MKCOLOUR_0XX0(x) (MKCOLOUR(0x00010100) * (uint)(x))
#define MKCOLOUR_X00X(x) (MKCOLOUR(0x01000001) * (uint)(x))
#define MKCOLOUR_XYXY(x, y) (MKCOLOUR_X0X0(x) | MKCOLOUR_0X0X(y))
#define MKCOLOUR_XYYX(x, y) (MKCOLOUR_X00X(x) | MKCOLOUR_0XX0(y))
#define MKCOLOUR_0000 MKCOLOUR_XXXX(0x00)
#define MKCOLOUR_0FF0 MKCOLOUR_0XX0(0xFF)
#define MKCOLOUR_F00F MKCOLOUR_X00X(0xFF)
#define MKCOLOUR_FFFF MKCOLOUR_XXXX(0xFF)
#include "table/heightmap_colours.h"
#include "table/darklight_colours.h"
/** Colour scheme of the smallmap. */
struct SmallMapColourScheme {
uint32 *height_colours; ///< Cached colours for each level in a map.
const uint32 *height_colours_base; ///< Base table for determining the colours
size_t colour_count; ///< The number of colours.
uint32 default_colour; ///< Default colour of the land.
};
extern SmallMapColourScheme _heightmap_schemes[];
struct AndOr {
uint32 mor;
uint32 mand;
};
static inline uint32 ApplyMask(uint32 colour, const AndOr *mask)
{
return (colour & mask->mand) | mask->mor;
}
/** Colour masks for "Contour" and "Routes" modes. */
static const AndOr _smallmap_contours_andor[] = {
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_CLEAR
{MKCOLOUR_0XX0(PC_GREY ), MKCOLOUR_F00F}, // MP_RAILWAY
{MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_ROAD
{MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_HOUSE
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TREES
{MKCOLOUR_XXXX(PC_LIGHT_BLUE), MKCOLOUR_0000}, // MP_STATION
{MKCOLOUR_XXXX(PC_WATER ), MKCOLOUR_0000}, // MP_WATER
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_VOID
{MKCOLOUR_XXXX(PC_DARK_RED ), MKCOLOUR_0000}, // MP_INDUSTRY
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TUNNELBRIDGE
{MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_OBJECT
{MKCOLOUR_0XX0(PC_GREY ), MKCOLOUR_F00F},
};
/** Colour masks for "Vehicles", "Industry", and "Vegetation" modes. */
static const AndOr _smallmap_vehicles_andor[] = {
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_CLEAR
{MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_RAILWAY
{MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_ROAD
{MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_HOUSE
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TREES
{MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_STATION
{MKCOLOUR_XXXX(PC_WATER ), MKCOLOUR_0000}, // MP_WATER
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_VOID
{MKCOLOUR_XXXX(PC_DARK_RED ), MKCOLOUR_0000}, // MP_INDUSTRY
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TUNNELBRIDGE
{MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_OBJECT
{MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F},
};
static const uint32 _vegetation_clear_bits[] = {
MKCOLOUR_XXXX(PC_GRASS_LAND), ///< full grass
MKCOLOUR_XXXX(PC_ROUGH_LAND), ///< rough land
MKCOLOUR_XXXX(PC_GREY), ///< rocks
MKCOLOUR_XXXX(PC_FIELDS), ///< fields
MKCOLOUR_XXXX(PC_LIGHT_BLUE), ///< snow
MKCOLOUR_XXXX(PC_ORANGE), ///< desert
MKCOLOUR_XXXX(PC_GRASS_LAND), ///< unused
MKCOLOUR_XXXX(PC_GRASS_LAND), ///< unused
};
#endif /* SMALLMAP_COLOURS_H */

@ -24,6 +24,7 @@
#include "window_func.h"
#include "company_base.h"
#include "smallmap_colours.h"
#include "smallmap_gui.h"
#include "table/strings.h"
@ -37,15 +38,6 @@ static int _smallmap_cargo_count; ///< Number of cargos in the link stats leg
/** Link stat colours shown in legenda. */
static uint8 _linkstat_colours_in_legenda[] = {0, 1, 3, 5, 7, 9, 11};
static const int NUM_NO_COMPANY_ENTRIES = 4; ///< Number of entries in the owner legend that are not companies.
static const uint8 PC_ROUGH_LAND = 0x52; ///< Dark green palette colour for rough land.
static const uint8 PC_GRASS_LAND = 0x54; ///< Dark green palette colour for grass land.
static const uint8 PC_BARE_LAND = 0x37; ///< Brown palette colour for bare land.
static const uint8 PC_FIELDS = 0x25; ///< Light brown palette colour for fields.
static const uint8 PC_TREES = 0x57; ///< Green palette colour for trees.
static const uint8 PC_WATER = 0xCA; ///< Dark blue palette colour for water.
/** Macro for ordinary entry of LegendAndColour */
#define MK(a, b) {a, b, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, false, false}
@ -133,7 +125,7 @@ static const LegendAndColour _legend_vegetation[] = {
MKEND()
};
static LegendAndColour _legend_land_owners[NUM_NO_COMPANY_ENTRIES + MAX_COMPANIES + 1] = {
LegendAndColour _legend_land_owners[NUM_NO_COMPANY_ENTRIES + MAX_COMPANIES + 1] = {
MO(PC_WATER, STR_SMALLMAP_LEGENDA_WATER),
MO(0x00, STR_SMALLMAP_LEGENDA_NO_OWNER), // This colour will vary depending on settings.
MO(PC_DARK_RED, STR_SMALLMAP_LEGENDA_TOWNS),
@ -155,17 +147,17 @@ static LegendAndColour _legend_linkstats[NUM_CARGO + lengthof(_linkstat_colours_
* Allow room for all industries, plus a terminator entry
* This is required in order to have the industry slots all filled up
*/
static LegendAndColour _legend_from_industries[NUM_INDUSTRYTYPES + 1];
LegendAndColour _legend_from_industries[NUM_INDUSTRYTYPES + 1];
/** For connecting industry type to position in industries list(small map legend) */
static uint _industry_to_list_pos[NUM_INDUSTRYTYPES];
uint _industry_to_list_pos[NUM_INDUSTRYTYPES];
/** Show heightmap in industry and owner mode of smallmap window. */
static bool _smallmap_show_heightmap = false;
bool _smallmap_show_heightmap = false;
/** Highlight a specific industry type */
static IndustryType _smallmap_industry_highlight = INVALID_INDUSTRYTYPE;
/** State of highlight blinking */
static bool _smallmap_industry_highlight_state;
/** For connecting company ID to position in owner list (small map legend) */
static uint _company_to_list_pos[MAX_COMPANIES];
uint _company_to_list_pos[MAX_COMPANIES];
/**
* Fills an array for the industries legends.
@ -241,35 +233,9 @@ static const LegendAndColour * const _legend_table[] = {
_legend_land_owners,
};
#define MKCOLOUR(x) TO_LE32X(x)
#define MKCOLOUR_XXXX(x) (MKCOLOUR(0x01010101) * (uint)(x))
#define MKCOLOUR_X0X0(x) (MKCOLOUR(0x01000100) * (uint)(x))
#define MKCOLOUR_0X0X(x) (MKCOLOUR(0x00010001) * (uint)(x))
#define MKCOLOUR_0XX0(x) (MKCOLOUR(0x00010100) * (uint)(x))
#define MKCOLOUR_X00X(x) (MKCOLOUR(0x01000001) * (uint)(x))
#define MKCOLOUR_XYXY(x, y) (MKCOLOUR_X0X0(x) | MKCOLOUR_0X0X(y))
#define MKCOLOUR_XYYX(x, y) (MKCOLOUR_X00X(x) | MKCOLOUR_0XX0(y))
#define MKCOLOUR_0000 MKCOLOUR_XXXX(0x00)
#define MKCOLOUR_0FF0 MKCOLOUR_0XX0(0xFF)
#define MKCOLOUR_F00F MKCOLOUR_X00X(0xFF)
#define MKCOLOUR_FFFF MKCOLOUR_XXXX(0xFF)
#include "table/heightmap_colours.h"
/** Colour scheme of the smallmap. */
struct SmallMapColourScheme {
uint32 *height_colours; ///< Cached colours for each level in a map.
const uint32 *height_colours_base; ///< Base table for determining the colours
size_t colour_count; ///< The number of colours.
uint32 default_colour; ///< Default colour of the land.
};
/** Available colour schemes for height maps. */
static SmallMapColourScheme _heightmap_schemes[] = {
{NULL, _green_map_heights, lengthof(_green_map_heights), MKCOLOUR_XXXX(0x54)}, ///< Green colour scheme.
SmallMapColourScheme _heightmap_schemes[] = {
{NULL, _green_map_heights, lengthof(_green_map_heights), MKCOLOUR_XXXX(0x5B)}, ///< Green colour scheme.
{NULL, _dark_green_map_heights, lengthof(_dark_green_map_heights), MKCOLOUR_XXXX(0x62)}, ///< Dark green colour scheme.
{NULL, _violet_map_heights, lengthof(_violet_map_heights), MKCOLOUR_XXXX(0x82)}, ///< Violet colour scheme.
};
@ -351,66 +317,6 @@ void BuildOwnerLegend()
_smallmap_company_count = i;
}
struct AndOr {
uint32 mor;
uint32 mand;
};
static inline uint32 ApplyMask(uint32 colour, const AndOr *mask)
{
return (colour & mask->mand) | mask->mor;
}
/** Colour masks for "Contour" and "Routes" modes. */
static const AndOr _smallmap_contours_andor[] = {
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_CLEAR
{MKCOLOUR_0XX0(PC_GREY ), MKCOLOUR_F00F}, // MP_RAILWAY
{MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_ROAD
{MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_HOUSE
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TREES
{MKCOLOUR_XXXX(PC_LIGHT_BLUE), MKCOLOUR_0000}, // MP_STATION
{MKCOLOUR_XXXX(PC_WATER ), MKCOLOUR_0000}, // MP_WATER
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_VOID
{MKCOLOUR_XXXX(PC_DARK_RED ), MKCOLOUR_0000}, // MP_INDUSTRY
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TUNNELBRIDGE
{MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_OBJECT
{MKCOLOUR_0XX0(PC_GREY ), MKCOLOUR_F00F},
};
/** Colour masks for "Vehicles", "Industry", and "Vegetation" modes. */
static const AndOr _smallmap_vehicles_andor[] = {
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_CLEAR
{MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_RAILWAY
{MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_ROAD
{MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_HOUSE
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TREES
{MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_STATION
{MKCOLOUR_XXXX(PC_WATER ), MKCOLOUR_0000}, // MP_WATER
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_VOID
{MKCOLOUR_XXXX(PC_DARK_RED ), MKCOLOUR_0000}, // MP_INDUSTRY
{MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TUNNELBRIDGE
{MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_OBJECT
{MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F},
};
/** Mapping of tile type to importance of the tile (higher number means more interesting to show). */
static const byte _tiletype_importance[] = {
2, // MP_CLEAR
8, // MP_RAILWAY
7, // MP_ROAD
5, // MP_HOUSE
2, // MP_TREES
9, // MP_STATION
2, // MP_WATER
1, // MP_VOID
6, // MP_INDUSTRY
8, // MP_TUNNELBRIDGE
2, // MP_OBJECT
0,
};
static inline TileType GetEffectiveTileType(TileIndex tile)
{
TileType t = GetTileType(tile);
@ -522,17 +428,6 @@ static inline uint32 GetSmallMapLinkStatsPixels(TileIndex tile, TileType t)
return _smallmap_show_heightmap ? GetSmallMapContoursPixels(tile, t) : GetSmallMapRoutesPixels(tile, t);
}
static const uint32 _vegetation_clear_bits[] = {
MKCOLOUR_XXXX(PC_GRASS_LAND), ///< full grass
MKCOLOUR_XXXX(PC_ROUGH_LAND), ///< rough land
MKCOLOUR_XXXX(PC_GREY), ///< rocks
MKCOLOUR_XXXX(PC_FIELDS), ///< fields
MKCOLOUR_XXXX(PC_LIGHT_BLUE), ///< snow
MKCOLOUR_XXXX(PC_ORANGE), ///< desert
MKCOLOUR_XXXX(PC_GRASS_LAND), ///< unused
MKCOLOUR_XXXX(PC_GRASS_LAND), ///< unused
};
/**
* Return the colour a tile would be displayed with in the smallmap in mode "Vegetation".
*
@ -592,6 +487,16 @@ static inline uint32 GetSmallMapOwnerPixels(TileIndex tile, TileType t)
return MKCOLOUR_XXXX(_legend_land_owners[_company_to_list_pos[o]].colour);
}
static void NotifyAllViewports(ViewportMapType map_type)
{
Window *w;
FOR_ALL_WINDOWS_FROM_BACK(w) {
if (w->viewport != NULL)
if (w->viewport->zoom >= ZOOM_LVL_DRAW_MAP && w->viewport->map_type == map_type)
w->InvalidateData();
}
}
/** Vehicle colours in #SMT_VEHICLES mode. Indexed by #VehicleTypeByte. */
static const byte _vehicle_type_colours[6] = {
PC_RED, PC_YELLOW, PC_LIGHT_BLUE, PC_WHITE, PC_BLACK, PC_RED
@ -1483,6 +1388,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
/* If click on industries label, find right industry type and enable/disable it. */
if (click_pos < _smallmap_industry_count) {
this->SelectLegendItem(click_pos, _legend_from_industries, _smallmap_industry_count);
NotifyAllViewports(VPMT_INDUSTRY);
}
} else if (this->map_type == SMT_LINKSTATS) {
if (click_pos < _smallmap_cargo_count) {
@ -1492,6 +1398,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
} else if (this->map_type == SMT_OWNER) {
if (click_pos < _smallmap_company_count) {
this->SelectLegendItem(click_pos, _legend_land_owners, _smallmap_company_count, NUM_NO_COMPANY_ENTRIES);
NotifyAllViewports(VPMT_OWNER);
}
}
this->SetDirty();
@ -1505,9 +1412,11 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
switch (this->map_type) {
case SMT_INDUSTRY:
tbl = _legend_from_industries;
NotifyAllViewports(VPMT_INDUSTRY);
break;
case SMT_OWNER:
tbl = &(_legend_land_owners[NUM_NO_COMPANY_ENTRIES]);
NotifyAllViewports(VPMT_OWNER);
break;
case SMT_LINKSTATS:
tbl = _legend_linkstats;
@ -1526,6 +1435,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
case WID_SM_SHOW_HEIGHT: // Enable/disable showing of heightmap.
_smallmap_show_heightmap = !_smallmap_show_heightmap;
this->SetWidgetLoweredState(WID_SM_SHOW_HEIGHT, _smallmap_show_heightmap);
NotifyAllViewports(VPMT_INDUSTRY);
this->SetDirty();
break;
}
@ -1572,7 +1482,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt)
{
if (widget != WID_SM_MAP || _scrolling_viewport) return false;
_scrolling_viewport = true;
_scrolling_viewport = this;
return true;
}

@ -20,9 +20,34 @@
#include "linkgraph/linkgraph_gui.h"
#include "widgets/smallmap_widget.h"
static const int NUM_NO_COMPANY_ENTRIES = 4; ///< Number of entries in the owner legend that are not companies.
/** Mapping of tile type to importance of the tile (higher number means more interesting to show). */
static const byte _tiletype_importance[] = {
2, // MP_CLEAR
8, // MP_RAILWAY
7, // MP_ROAD
5, // MP_HOUSE
2, // MP_TREES
9, // MP_STATION
2, // MP_WATER
1, // MP_VOID
6, // MP_INDUSTRY
8, // MP_TUNNELBRIDGE
2, // MP_OBJECT
0,
};
/* set up the cargos to be displayed in the smallmap's route legend */
void BuildLinkStatsLegend();
struct TunnelBridgeToMap {
TileIndex from_tile;
TileIndex to_tile;
uint8 colour;
};
typedef SmallVector<TunnelBridgeToMap, 64> TunnelBridgeToMapVector;
void BuildIndustriesLegend();
void ShowSmallMap();
void BuildLandLegend();
@ -147,7 +172,6 @@ protected:
return Company::IsValidID(_local_company) ? 1U << _local_company : 0xffffffff;
}
void RebuildColourIndexIfNecessary();
uint GetNumberRowsLegend(uint columns) const;
void SelectLegendItem(int click_pos, LegendAndColour *legend, int end_legend_item, int begin_legend_item = 0);
void SwitchMapType(SmallMapType map_type);
@ -176,6 +200,8 @@ public:
SmallMapWindow(WindowDesc *desc, int window_number);
virtual ~SmallMapWindow() { delete this->overlay; }
static void RebuildColourIndexIfNecessary();
void SmallMapCenterOnCurrentPos();
Point GetStationMiddle(const Station *st) const;

@ -189,7 +189,7 @@ static void StartSound(SoundID sound_id, float pan, uint volume)
}
static const byte _vol_factor_by_zoom[] = {255, 255, 255, 190, 134, 87};
static const byte _vol_factor_by_zoom[] = {255, 255, 255, 190, 134, 87, 10, 1, 1, 1};
assert_compile(lengthof(_vol_factor_by_zoom) == ZOOM_LVL_COUNT);
static const byte _sound_base_vol[] = {

@ -853,6 +853,102 @@ void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator)
}
}
/**
* Reads a sprite and finds its most representative colour.
* @param sprite Sprite to read.
* @param palette_id Palette for remapping colours.
* @return if blitter supports 32bpp, average Colour.data else a palette index.
*/
uint32 GetSpriteMainColour(SpriteID sprite_id, PaletteID palette_id)
{
if (!SpriteExists(sprite_id)) return 0;
SpriteCache *sc = GetSpriteCache(sprite_id);
if (sc->type != ST_NORMAL) return 0;
const byte * const remap = (palette_id == PAL_NONE ? NULL : GetNonSprite(GB(palette_id, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1);
uint8 file_slot = sc->file_slot;
size_t file_pos = sc->file_pos;
SpriteLoader::Sprite sprites[ZOOM_LVL_COUNT];
SpriteLoader::Sprite *sprite = &sprites[ZOOM_LVL_SHIFT];
sprites[ZOOM_LVL_NORMAL].type = ST_NORMAL;
SpriteLoaderGrf sprite_loader(sc->container_ver);
uint8 sprite_avail;
const uint8 screen_depth = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
/* Try to read the 32bpp sprite first. */
if (screen_depth == 32) {
sprite_avail = sprite_loader.LoadSprite(sprites, file_slot, file_pos, ST_NORMAL, true);
if (sprite_avail & ZOOM_LVL_BASE) {
/* Return the average colour. */
uint32 r = 0, g = 0, b = 0, cnt = 0;
SpriteLoader::CommonPixel *pixel = sprite->data;
for (uint x = sprite->width * sprite->height; x != 0; x--) {
if (pixel->a) {
if (remap && pixel->m) {
const Colour c = _cur_palette.palette[remap[pixel->m]];
if (c.a) {
r += c.r;
g += c.g;
b += c.b;
cnt++;
}
} else {
r += pixel->r;
g += pixel->g;
b += pixel->b;
cnt++;
}
}
pixel++;
}
return cnt ? Colour(r / cnt, g / cnt, b / cnt).data : 0;
}
}
/* No 32bpp, try 8bpp. */
sprite_avail = sprite_loader.LoadSprite(sprites, file_slot, file_pos, ST_NORMAL, false);
if (sprite_avail & ZOOM_LVL_BASE) {
SpriteLoader::CommonPixel *pixel = sprite->data;
if (screen_depth == 32) {
/* Return the average colour. */
uint32 r = 0, g = 0, b = 0, cnt = 0;
for (uint x = sprite->width * sprite->height; x != 0; x--) {
if (pixel->a) {
const uint col_index = remap ? remap[pixel->m] : pixel->m;
const Colour c = _cur_palette.palette[col_index];
r += c.r;
g += c.g;
b += c.b;
cnt++;
}
pixel++;
}
return cnt ? Colour(r / cnt, g / cnt, b / cnt).data : 0;
} else {
/* Return the most used indexed colour. */
int cnt[256];
memset(cnt, 0, sizeof(cnt));
for (uint x = sprite->width * sprite->height; x != 0; x--) {
cnt[remap ? remap[pixel->m] : pixel->m]++;
pixel++;
}
int cnt_max = -1;
uint32 rk = 0;
for (uint x = 1; x < lengthof(cnt); x++) {
if (cnt[x] > cnt_max) {
rk = x;
cnt_max = cnt[x];
}
}
return rk;
}
}
return 0;
}
static void GfxInitSpriteCache()
{

@ -57,4 +57,6 @@ bool LoadNextSprite(int load_index, byte file_index, uint file_sprite_id, byte c
bool SkipSpriteData(byte type, uint16 num);
void DupSprite(SpriteID old_spr, SpriteID new_spr);
uint32 GetSpriteMainColour(SpriteID sprite_id, PaletteID palette_id);
#endif /* SPRITECACHE_H */

@ -219,7 +219,7 @@ void Station::MarkTilesDirty(bool cargo_change) const
for (h = 0; h < train_station.h; h++) {
for (w = 0; w < train_station.w; w++) {
if (this->TileBelongsToRailStation(tile)) {
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
tile += TileDiffXY(1, 0);
}

@ -514,4 +514,19 @@ static inline void free(const void *ptr)
#define IGNORE_UNINITIALIZED_WARNING_STOP
#endif
/**
* Using _mm_prefetch() with gcc implies the compile flag -msse.
* This is not the case with __builtin_prefetch() so the latter can be used in normal .cpp files.
*/
#if defined(_MSC_VER)
#define INCLUDE_FOR_PREFETCH_NTA <xmmintrin.h>
#define PREFETCH_NTA(address) _mm_prefetch((const char *) (address), _MM_HINT_NTA);
#elif defined(__GNUC__)
#define INCLUDE_FOR_PREFETCH_NTA "stdafx.h"
#define PREFETCH_NTA(address) __builtin_prefetch((const void *) (address), 0, 0);
#else
#define INCLUDE_FOR_PREFETCH_NTA "stdafx.h"
#define PREFETCH_NTA(address)
#endif
#endif /* STDAFX_H */

@ -0,0 +1,52 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file darklight_colours.h The colour tables to lighten and darken.
*/
static const byte _lighten_colour[] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0xFF, // 0
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x0F, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x0F, // 1
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x0F, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 2
0x31, 0x0F, 0x33, 0x34, 0x45, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x0F, 0x3D, 0x3E, 0x3F, 0x40, // 3
0x41, 0x42, 0x43, 0x44, 0x45, 0x0F, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x0F, // 4
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x0F, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x0F, // 5
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x0F, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x0F, // 6
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x0F, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x0F, // 7
0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x0F, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x0F, // 8
0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x0F, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, // 9
0xA1, 0x0F, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x0F, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, // A
0xB1, 0x0F, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0x0F, // B
0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0x0F, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0x0F, 0xCF, 0xD0, // C
0xD1, 0x0F, 0x0F, 0xD2, 0xD3, 0xD4, 0xD5, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0x0F, // D
0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0x0F, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0x0F, 0xE3, // E
0xE8, 0xF2, 0xF3, 0xCE, 0x44, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x0F, 0xFC, 0xFD, 0xFF, // F
};
static const byte _darken_colour[] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0
0x02, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x02, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, // 1
0x02, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x02, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, // 2
0x2F, 0x30, 0x42, 0x32, 0x33, 0x02, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x02, 0x3C, 0x3D, 0x3E, // 3
0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x01, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, // 4
0x02, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x02, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, // 5
0x02, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x02, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 6
0x69, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0xEF, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, // 7
0x02, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x02, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, // 8
0x02, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x02, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, // 9
0x9F, 0xA0, 0xB4, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0x02, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, // A
0xAF, 0xB0, 0x02, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, // B
0x3F, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0x02, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xF3, 0xCE, // C
0xCF, 0xD0, 0xD3, 0xD4, 0xD5, 0xD6, 0xDF, 0x02, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, // D
0xE1, 0xE2, 0x02, 0xEF, 0xE3, 0xE4, 0xE5, 0xE6, 0xB8, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0x02, // E
0xB5, 0x02, 0xF1, 0xF2, 0x43, 0x02, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFE, 0xF5, 0x0F // F
};

@ -2782,6 +2782,104 @@ strhelp = STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER_HELPTEXT
strval = STR_JUST_COMMA
cat = SC_BASIC
[SDTC_BOOL]
var = gui.viewport_map_scan_surroundings
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = true
str = STR_CONFIG_SETTING_VIEWPORT_MAP_SCAN_SURROUNDINGS
proc = RedrawScreen
[SDTC_BOOL]
var = gui.show_slopes_on_viewport_map
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = true
str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SLOPES
proc = RedrawScreen
[SDTC_BOOL]
var = gui.show_bridges_on_map
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = true
str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_BRIDGES
proc = RedrawScreen
[SDTC_BOOL]
var = gui.show_tunnels_on_map
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = true
str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_TUNNELS
proc = RedrawScreen
[SDTC_VAR]
var = gui.show_vehicle_route
type = SLE_UINT32
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SGF_MULTISTRING
def = 0
min = 0
max = 1
interval = 1
str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_VEHICLE_ROUTE
strval = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_VEHICLE_ROUTE_NO
proc = RedrawScreen
[SDTC_VAR]
var = gui.dash_level_of_route_lines
type = SLE_UINT32
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SGF_0ISDISABLED
def = 0
min = 0
max = 10
interval = 1
str = STR_CONFIG_SETTING_VIEWPORT_MAP_DRAW_ROUTE_DASH
strval = STR_CONFIG_SETTING_VIEWPORT_MAP_DRAW_ROUTE_DASH_VALUE
proc = RedrawScreen
cat = SC_EXPERT
[SDTC_BOOL]
var = gui.use_owner_colour_for_tunnelbridge
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = false
str = STR_CONFIG_SETTING_VIEWPORT_MAP_USE_OWNER_COLOUR_BRIDGE_TUNNEL
proc = RedrawScreen
[SDTC_VAR]
var = gui.show_scrolling_viewport_on_map
type = SLE_UINT32
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SGF_MULTISTRING
def = 3
min = 0
max = 3
interval = 1
str = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SCROLLING_VP
strval = STR_CONFIG_SETTING_VIEWPORT_MAP_SHOW_SCROLLING_VP_NOTHING
[SDTC_VAR]
var = gui.default_viewport_map_mode
type = SLE_UINT32
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SGF_MULTISTRING
def = 0
min = 0
max = 2
interval = 1
str = STR_CONFIG_SETTING_VIEWPORT_MAP_DEFAULT_MODE
strval = STR_CONFIG_SETTING_VIEWPORT_MAP_DEFAULT_MODE_VEGETATION
[SDTC_VAR]
var = gui.action_when_viewport_map_is_dblclicked
type = SLE_UINT32
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SGF_MULTISTRING
def = 1
min = 0
max = 2
interval = 1
str = STR_CONFIG_SETTING_VIEWPORT_MAP_ACTION_DBLCLICK
strval = STR_CONFIG_SETTING_VIEWPORT_MAP_ACTION_DBLCLICK_DO_NOTHING
[SDTC_BOOL]
var = gui.pause_on_newgame
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
@ -3130,6 +3228,13 @@ strhelp = STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT
strval = STR_JUST_COMMA
proc = RedrawScreen
[SDTC_BOOL]
var = gui.show_vehicle_route_steps
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = true
str = STR_CONFIG_SETTING_SHOW_VEHICLE_ROUTE_STEPS
proc = RedrawScreen
; For the dedicated build we'll enable dates in logs by default.
[SDTC_BOOL]
ifdef = DEDICATED

@ -163,7 +163,15 @@ static const SpriteID SPR_WINDOW_DEFSIZE = SPR_OPENTTD_BASE + 168;
static const SpriteID SPR_IMG_CARGOFLOW = SPR_OPENTTD_BASE + 174;
static const SpriteID SPR_SIGNALS_BASE = SPR_OPENTTD_BASE + OPENTTD_SPRITE_COUNT;
/** Sprites for the route step marker. */
static const SpriteID SPR_ROUTE_STEP_BASE = SPR_OPENTTD_BASE + OPENTTD_SPRITE_COUNT;
static const SpriteID SPR_ROUTE_STEP_TOP = SPR_ROUTE_STEP_BASE + 0;
static const SpriteID SPR_ROUTE_STEP_MIDDLE = SPR_ROUTE_STEP_BASE + 1;
static const SpriteID SPR_ROUTE_STEP_BOTTOM = SPR_ROUTE_STEP_BASE + 2;
static const SpriteID SPR_ROUTE_STEP_BOTTOM_SHADOW = SPR_ROUTE_STEP_BASE + 3;
static const SpriteID ROUTE_STEP_SPRITE_COUNT = 4;
static const SpriteID SPR_SIGNALS_BASE = SPR_ROUTE_STEP_BASE + ROUTE_STEP_SPRITE_COUNT;
static const uint16 PRESIGNAL_SPRITE_COUNT = 48;
static const uint16 PRESIGNAL_AND_SEMAPHORE_SPRITE_COUNT = 112;
static const uint16 PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT = 240;

@ -12,8 +12,11 @@
#ifndef TREE_LAND_H
#define TREE_LAND_H
#include "../sprite.h"
static const byte _tree_base_by_landscape[4] = {0, 12, 20, 32};
static const byte _tree_count_by_landscape[4] = {12, 8, 12, 9};
#define MAX_TREE_COUNT_BY_LANDSCAPE 12
struct TreePos {
uint8 x;
@ -227,4 +230,18 @@ static const PalSpriteID _tree_layout_sprite[164 + (79 - 48 + 1)][4] = {
{ { 0x716, PAL_NONE }, { 0x701, PAL_NONE }, { 0x6fa, PAL_NONE }, { 0x716, PAL_NONE } }, // 31
};
/** Tree Sprites with their palettes */
static const PalSpriteID _tree_sprites[] = {
{ 1621, PAL_NONE }, { 1587, PAL_NONE }, { 1656, PAL_NONE }, { 1579, PAL_NONE },
{ 1607, PAL_NONE }, { 1593, PAL_NONE }, { 1614, PAL_NONE }, { 1586, PAL_NONE },
{ 1663, PAL_NONE }, { 1677, PAL_NONE }, { 1691, PAL_NONE }, { 1705, PAL_NONE },
{ 1711, PAL_NONE }, { 1746, PAL_NONE }, { 1753, PAL_NONE }, { 1732, PAL_NONE },
{ 1739, PAL_NONE }, { 1718, PAL_NONE }, { 1725, PAL_NONE }, { 1760, PAL_NONE },
{ 1838, PAL_NONE }, { 1844, PAL_NONE }, { 1866, PAL_NONE }, { 1871, PAL_NONE },
{ 1899, PAL_NONE }, { 1935, PAL_NONE }, { 1928, PAL_NONE }, { 1915, PAL_NONE },
{ 1887, PAL_NONE }, { 1908, PAL_NONE }, { 1824, PAL_NONE }, { 1943, PAL_NONE },
{ 1950, PAL_NONE }, { 1957, PALETTE_TO_GREEN }, { 1964, PALETTE_TO_RED }, { 1971, PAL_NONE },
{ 1978, PAL_NONE }, { 1985, PALETTE_TO_RED, }, { 1992, PALETTE_TO_PALE_GREEN }, { 1999, PALETTE_TO_YELLOW }, { 2006, PALETTE_TO_RED }
};
#endif /* TREE_LAND_H */

@ -12,6 +12,8 @@
#ifndef TILEAREA_TYPE_H
#define TILEAREA_TYPE_H
#include "stdafx.h"
#include INCLUDE_FOR_PREFETCH_NTA
#include "map_func.h"
/** Represents the covered area of e.g. a rail station */
@ -184,6 +186,65 @@ public:
}
};
/** Iterator to iterate over a tile area (rectangle) of the map.
* It prefetches tiles once per row.
*/
class OrthogonalPrefetchTileIterator {
private:
TileIndex tile; ///< The current tile we are at.
int w; ///< The width of the iterated area.
int x; ///< The current 'x' position in the rectangle.
int y; ///< The current 'y' position in the rectangle.
public:
/**
* Construct the iterator.
* @param ta Area, i.e. begin point and width/height of to-be-iterated area.
*/
OrthogonalPrefetchTileIterator(const TileArea &ta) : tile(ta.w == 0 || ta.h == 0 ? INVALID_TILE : ta.tile), w(ta.w), x(ta.w), y(ta.h)
{
PREFETCH_NTA(&_m[ta.tile]);
}
/** Some compilers really like this. */
virtual ~OrthogonalPrefetchTileIterator()
{
}
/**
* Get the tile we are currently at.
* @return The tile we are at, or INVALID_TILE when we're done.
*/
inline operator TileIndex () const
{
return this->tile;
}
/**
* Move ourselves to the next tile in the rectangle on the map.
*/
inline OrthogonalPrefetchTileIterator& operator ++()
{
assert(this->tile != INVALID_TILE);
if (--this->x > 0) {
this->tile++;
} else if (--this->y > 0) {
this->x = this->w;
this->tile += TileDiffXY(1, 1) - this->w;
PREFETCH_NTA(&_m[tile]);
} else {
this->tile = INVALID_TILE;
}
return *this;
}
virtual OrthogonalPrefetchTileIterator *Clone() const
{
return new OrthogonalPrefetchTileIterator(*this);
}
};
/** Iterator to iterate over a diagonal area of the map. */
class DiagonalTileIterator : public TileIterator {
private:
@ -230,5 +291,6 @@ public:
* @param ta The tile area to search over.
*/
#define TILE_AREA_LOOP(var, ta) for (OrthogonalTileIterator var(ta); var != INVALID_TILE; ++var)
#define TILE_AREA_LOOP_WITH_PREFETCH(var, ta) for (OrthogonalPrefetchTileIterator var(ta); var != INVALID_TILE; ++var)
#endif /* TILEAREA_TYPE_H */

@ -24,6 +24,7 @@
#include "date_gui.h"
#include "vehicle_gui.h"
#include "settings_type.h"
#include "viewport_func.h"
#include "widgets/timetable_widget.h"
@ -171,6 +172,13 @@ struct TimetableWindow : Window {
this->owner = this->vehicle->owner;
}
~TimetableWindow()
{
if (!FocusWindowById(WC_VEHICLE_VIEW, this->window_number)) {
MarkAllRouteStepsDirty(this);
}
}
/**
* Build the arrival-departure list for a given vehicle
* @param v the vehicle to make the list for
@ -647,6 +655,27 @@ struct TimetableWindow : Window {
this->GetWidget<NWidgetStacked>(WID_VT_ARRIVAL_DEPARTURE_SELECTION)->SetDisplayedPlane(_settings_client.gui.timetable_arrival_departure ? 0 : SZSP_NONE);
this->GetWidget<NWidgetStacked>(WID_VT_EXPECTED_SELECTION)->SetDisplayedPlane(_settings_client.gui.timetable_arrival_departure ? 0 : 1);
}
virtual void OnFocus(Window *previously_focused_window)
{
if (HasFocusedVehicleChanged(this->window_number, previously_focused_window)) {
MarkAllRoutePathsDirty(this->vehicle);
MarkAllRouteStepsDirty(this);
}
}
virtual void OnFocusLost(Window *newly_focused_window)
{
if (HasFocusedVehicleChanged(this->window_number, newly_focused_window)) {
MarkAllRoutePathsDirty(this->vehicle);
MarkAllRouteStepsDirty(this);
}
}
const Vehicle *GetVehicle()
{
return this->vehicle;
}
};
static const NWidgetPart _nested_timetable_widgets[] = {

@ -46,6 +46,7 @@
#include "game/game.hpp"
#include "goal_base.h"
#include "story_base.h"
#include "plans_func.h"
#include "widgets/toolbar_widget.h"
@ -447,6 +448,7 @@ enum MapMenuEntries {
MME_SHOW_SIGNLISTS,
MME_SHOW_TOWNDIRECTORY,
MME_SHOW_INDUSTRYDIRECTORY,
MME_SHOW_PLANS,
};
static CallBackFunction ToolbarMapClick(Window *w)
@ -456,6 +458,7 @@ static CallBackFunction ToolbarMapClick(Window *w)
*list->Append() = new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEW_PORT, MME_SHOW_EXTRAVIEWPORTS, false);
*list->Append() = new DropDownListStringItem(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH, false);
*list->Append() = new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false);
*list->Append() = new DropDownListStringItem(STR_MAP_MENU_PLAN_LIST, MME_SHOW_PLANS, false);
PopupMainToolbMenu(w, WID_TN_SMALL_MAP, list, 0);
return CBF_NONE;
}
@ -487,6 +490,7 @@ static CallBackFunction MenuClickMap(int index)
case MME_SHOW_SIGNLISTS: ShowSignList(); break;
case MME_SHOW_TOWNDIRECTORY: ShowTownDirectory(); break;
case MME_SHOW_INDUSTRYDIRECTORY: ShowIndustryDirectory(); break;
case MME_SHOW_PLANS: ShowPlansWindow(); break;
}
return CBF_NONE;
}
@ -605,7 +609,7 @@ static CallBackFunction MenuClickCompany(int index)
if (_network_server) {
DoCommandP(0, 0, _network_own_client_id, CMD_COMPANY_CTRL);
} else {
NetworkSendCommand(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company);
NetworkSendCommand(0, 0, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company, 0);
}
return CBF_NONE;
@ -1648,6 +1652,7 @@ enum MainToolbarHotkeys {
MTHK_EXTRA_VIEWPORT,
MTHK_CLIENT_LIST,
MTHK_SIGN_LIST,
MTHK_PLAN_LIST,
};
/** Main toolbar. */
@ -1738,6 +1743,7 @@ struct MainToolbarWindow : Window {
case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break;
#endif
case MTHK_SIGN_LIST: ShowSignList(); break;
case MTHK_PLAN_LIST: ShowPlansWindow(); break;
default: return ES_NOT_HANDLED;
}
return ES_HANDLED;
@ -1843,6 +1849,7 @@ static Hotkey maintoolbar_hotkeys[] = {
Hotkey((uint16)0, "client_list", MTHK_CLIENT_LIST),
#endif
Hotkey((uint16)0, "sign_list", MTHK_SIGN_LIST),
Hotkey('P', "plan_list", MTHK_PLAN_LIST),
HOTKEY_LIST_END
};
HotkeyList MainToolbarWindow::hotkeys("maintoolbar", maintoolbar_hotkeys);

@ -330,7 +330,7 @@ static void AnimateTile_Town(TileIndex tile)
DeleteAnimatedTile(tile);
}
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
/**
@ -440,7 +440,7 @@ static void MakeSingleHouseBigger(TileIndex tile)
ChangePopulation(Town::GetByTile(tile), HouseSpec::Get(GetHouseType(tile))->population);
ResetHouseAge(tile);
}
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
/**

@ -1691,7 +1691,7 @@ void UpdateLevelCrossing(TileIndex tile, bool sound)
if (_settings_client.sound.ambient) SndPlayTileFx(SND_0E_LEVEL_CROSSING, tile);
}
SetCrossingBarred(tile, new_state);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
}
@ -1706,7 +1706,7 @@ static inline void MaybeBarCrossingWithSound(TileIndex tile)
if (!IsCrossingBarred(tile)) {
BarCrossing(tile);
if (_settings_client.sound.ambient) SndPlayTileFx(SND_0E_LEVEL_CROSSING, tile);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
}
@ -2170,7 +2170,7 @@ static bool CheckTrainStayInDepot(Train *v)
}
SetDepotReservation(v->tile, true);
if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(v->tile);
if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(v->tile, ZOOM_LVL_DRAW_MAP);
VehicleServiceInDepot(v);
SetWindowClassesDirty(WC_TRAINS_LIST);
@ -2212,8 +2212,8 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_
SetTunnelBridgeReservation(end, false);
if (_settings_client.gui.show_track_reservation) {
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(end);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
MarkTileDirtyByTile(end, ZOOM_LVL_DRAW_MAP);
}
}
}
@ -2278,7 +2278,7 @@ void FreeTrainTrackReservation(const Train *v, TileIndex origin, Trackdir orig_t
} else {
/* Turn the signal back to red. */
SetSignalStateByTrackdir(tile, td, SIGNAL_STATE_RED);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
} else if (HasSignalOnTrackdir(tile, ReverseTrackdir(td)) && IsOnewaySignal(tile, TrackdirToTrack(td))) {
break;
@ -2553,7 +2553,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
if (res_dest.okay) {
/* Got a valid reservation that ends at a safe target, quick exit. */
if (got_reservation != NULL) *got_reservation = true;
if (changed_signal) MarkTileDirtyByTile(tile);
if (changed_signal) MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir()));
return best_track;
}
@ -2612,7 +2612,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
best_track = FindFirstTrack(res);
TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir()));
if (got_reservation != NULL) *got_reservation = true;
if (changed_signal) MarkTileDirtyByTile(tile);
if (changed_signal) MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
} else {
FreeTrainTrackReservation(v);
if (mark_stuck) MarkTrainAsStuck(v);
@ -2660,7 +2660,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir()));
if (changed_signal) MarkTileDirtyByTile(tile);
if (changed_signal) MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
return best_track;
}
@ -2713,7 +2713,7 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay)
/* If we are in a depot, tentatively reserve the depot. */
if (v->track == TRACK_BIT_DEPOT) {
SetDepotReservation(v->tile, true);
if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(v->tile);
if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(v->tile, ZOOM_LVL_DRAW_MAP);
}
DiagDirection exitdir = TrackdirToExitdir(origin.trackdir);

@ -363,7 +363,7 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
if (flags & DC_EXEC) {
AddTreeCount(tile, 1);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
if (c != NULL) c->tree_limit -= 1 << 16;
}
/* 2x as expensive to add more trees to an existing tile */
@ -429,7 +429,7 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
/* Plant full grown trees in scenario editor */
PlantTreesOnTile(tile, treetype, 0, _game_mode == GM_EDITOR ? 3 : 0);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
if (c != NULL) c->tree_limit -= 1 << 16;
/* When planting rainforest-trees, set tropiczone to rainforest in editor. */
@ -581,7 +581,7 @@ static void TileLoopTreesDesert(TileIndex tile)
case TROPICZONE_DESERT:
if (GetTreeGround(tile) != TREE_GROUND_SNOW_DESERT) {
SetTreeGroundDensity(tile, TREE_GROUND_SNOW_DESERT, 3);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
break;
@ -630,7 +630,7 @@ static void TileLoopTreesAlps(TileIndex tile)
return;
}
}
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
static void TileLoop_Trees(TileIndex tile)
@ -653,7 +653,7 @@ static void TileLoop_Trees(TileIndex tile)
uint density = GetTreeDensity(tile);
if (density < 3) {
SetTreeGroundDensity(tile, TREE_GROUND_GRASS, density + 1);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
}
if (GetTreeCounter(tile) < 15) {
@ -746,7 +746,7 @@ static void TileLoop_Trees(TileIndex tile)
break;
}
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
}
void OnTick_Trees()

@ -29,21 +29,6 @@
void PlaceTreesRandomly();
/** Tree Sprites with their palettes */
const PalSpriteID tree_sprites[] = {
{ 1621, PAL_NONE }, { 1587, PAL_NONE }, { 1656, PAL_NONE }, { 1579, PAL_NONE },
{ 1607, PAL_NONE }, { 1593, PAL_NONE }, { 1614, PAL_NONE }, { 1586, PAL_NONE },
{ 1663, PAL_NONE }, { 1677, PAL_NONE }, { 1691, PAL_NONE }, { 1705, PAL_NONE },
{ 1711, PAL_NONE }, { 1746, PAL_NONE }, { 1753, PAL_NONE }, { 1732, PAL_NONE },
{ 1739, PAL_NONE }, { 1718, PAL_NONE }, { 1725, PAL_NONE }, { 1760, PAL_NONE },
{ 1838, PAL_NONE }, { 1844, PAL_NONE }, { 1866, PAL_NONE }, { 1871, PAL_NONE },
{ 1899, PAL_NONE }, { 1935, PAL_NONE }, { 1928, PAL_NONE }, { 1915, PAL_NONE },
{ 1887, PAL_NONE }, { 1908, PAL_NONE }, { 1824, PAL_NONE }, { 1943, PAL_NONE },
{ 1950, PAL_NONE }, { 1957, PALETTE_TO_GREEN }, { 1964, PALETTE_TO_RED }, { 1971, PAL_NONE },
{ 1978, PAL_NONE }, { 1985, PALETTE_TO_RED, }, { 1992, PALETTE_TO_PALE_GREEN }, { 1999, PALETTE_TO_YELLOW }, { 2006, PALETTE_TO_RED }
};
/**
* The build trees window.
*/
@ -75,8 +60,8 @@ public:
offset.y = 0;
for (int i = this->base; i < this->base + this->count; i++) {
if (i >= (int)lengthof(tree_sprites)) return size;
this_size = GetSpriteSize(tree_sprites[i].sprite, &offset);
if (i >= (int)lengthof(_tree_sprites)) return size;
this_size = GetSpriteSize(_tree_sprites[i].sprite, &offset);
size.width = max<int>(size.width, 2 * max<int>(this_size.width, -offset.x));
size.height = max<int>(size.height, max<int>(this_size.height, -offset.y));
}
@ -108,7 +93,7 @@ public:
int i = this->base + widget - WID_BT_TYPE_11;
/* Trees "grow" in the centre on the bottom line of the buttons */
DrawSprite(tree_sprites[i].sprite, tree_sprites[i].pal, (r.left + r.right) / 2 + WD_FRAMERECT_LEFT, r.bottom - 7);
DrawSprite(_tree_sprites[i].sprite, _tree_sprites[i].pal, (r.left + r.right) / 2 + WD_FRAMERECT_LEFT, r.bottom - 7);
}
virtual void OnClick(Point pt, int widget, int click_count)

@ -52,6 +52,7 @@
#include "gamelog.h"
#include "linkgraph/linkgraph.h"
#include "linkgraph/refresh.h"
#include "blitter/factory.hpp"
#include "table/strings.h"
@ -1081,6 +1082,62 @@ void ViewportAddVehicles(DrawPixelInfo *dpi)
}
}
void ViewportMapDrawVehicles(DrawPixelInfo *dpi)
{
/* The bounding rectangle */
const int l = dpi->left;
const int r = dpi->left + dpi->width;
const int t = dpi->top;
const int b = dpi->top + dpi->height;
/* The hash area to scan */
int xl, xu, yl, yu;
if (dpi->width + (70 * ZOOM_LVL_BASE) < (1 << (7 + 6 + ZOOM_LVL_SHIFT))) {
xl = GB(l - (70 * ZOOM_LVL_BASE), 7 + ZOOM_LVL_SHIFT, 6);
xu = GB(r, 7 + ZOOM_LVL_SHIFT, 6);
} else {
/* scan whole hash row */
xl = 0;
xu = 0x3F;
}
if (dpi->height + (70 * ZOOM_LVL_BASE) < (1 << (6 + 6 + ZOOM_LVL_SHIFT))) {
yl = GB(t - (70 * ZOOM_LVL_BASE), 6 + ZOOM_LVL_SHIFT, 6) << 6;
yu = GB(b, 6 + ZOOM_LVL_SHIFT, 6) << 6;
} else {
/* scan whole column */
yl = 0;
yu = 0x3F << 6;
}
const int w = UnScaleByZoom(dpi->width, dpi->zoom);
const int h = UnScaleByZoom(dpi->height, dpi->zoom);
Blitter *blitter = BlitterFactory::GetCurrentBlitter();
for (int y = yl;; y = (y + (1 << 6)) & (0x3F << 6)) {
for (int x = xl;; x = (x + 1) & 0x3F) {
const Vehicle *v = _vehicle_viewport_hash[x + y]; // already masked & 0xFFF
while (v != NULL) {
if (!(v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) && (v->type != VEH_EFFECT)) {
Point pt = RemapCoords(v->x_pos, v->y_pos, v->z_pos);
const int pixel_x = UnScaleByZoomLower(pt.x - dpi->left, dpi->zoom);
if (IsInsideMM(pixel_x, 0, w)) {
const int pixel_y = UnScaleByZoomLower(pt.y - dpi->top, dpi->zoom);
if (IsInsideMM(pixel_y, 0, h))
blitter->SetPixel(dpi->dst_ptr, pixel_x, pixel_y, PC_WHITE);
}
}
v = v->hash_viewport_next;
}
if (x == xu) break;
}
if (y == yu) break;
}
}
/**
* Find the vehicle close to the clicked coordinates.
* @param vp Viewport clicked in.
@ -1355,7 +1412,7 @@ void VehicleEnterDepot(Vehicle *v)
SetWindowClassesDirty(WC_TRAINS_LIST);
/* Clear path reservation */
SetDepotReservation(t->tile, false);
if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(t->tile);
if (_settings_client.gui.show_track_reservation) MarkTileDirtyByTile(t->tile, ZOOM_LVL_DRAW_MAP);
UpdateSignalsOnSegment(t->tile, INVALID_DIAGDIR, t->owner);
t->wait_counter = 0;
@ -1500,7 +1557,8 @@ void Vehicle::UpdateViewport(bool dirty)
min(old_coord.left, this->coord.left),
min(old_coord.top, this->coord.top),
max(old_coord.right, this->coord.right) + 1 * ZOOM_LVL_BASE,
max(old_coord.bottom, this->coord.bottom) + 1 * ZOOM_LVL_BASE
max(old_coord.bottom, this->coord.bottom) + 1 * ZOOM_LVL_BASE,
this->type != VEH_EFFECT ? ZOOM_LVL_END : ZOOM_LVL_DRAW_MAP
);
}
}

@ -58,6 +58,7 @@ void ResetVehicleColourMap();
byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_type);
void ViewportAddVehicles(DrawPixelInfo *dpi);
void ViewportMapDrawVehicles(DrawPixelInfo *dpi);
void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRFBugs bug_type, bool critical);
CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore = NULL);

@ -605,6 +605,32 @@ struct RefitWindow : public Window {
this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0);
}
~RefitWindow()
{
if (this->window_number != INVALID_VEHICLE) {
if (!FocusWindowById(WC_VEHICLE_VIEW, this->window_number)) {
if (this->window_number != INVALID_VEHICLE) MarkAllRoutePathsDirty(Vehicle::Get(this->window_number));
MarkAllRouteStepsDirty(this);
}
}
}
virtual void OnFocus(Window *previously_focused_window)
{
if (HasFocusedVehicleChanged(this->window_number, previously_focused_window)) {
if (this->window_number != INVALID_VEHICLE) MarkAllRoutePathsDirty(Vehicle::Get(this->window_number));
MarkAllRouteStepsDirty(this);
}
}
virtual void OnFocusLost(Window *newly_focused_window)
{
if (HasFocusedVehicleChanged(this->window_number, newly_focused_window)) {
if (this->window_number != INVALID_VEHICLE) MarkAllRoutePathsDirty(Vehicle::Get(this->window_number));
MarkAllRouteStepsDirty(this);
}
}
virtual void OnInit()
{
if (this->cargo != NULL) {
@ -1614,7 +1640,7 @@ public:
case WID_VL_SORT_BY_PULLDOWN:// Select sorting criteria dropdown menu
ShowDropDownMenu(this, this->vehicle_sorter_names, this->vehicles.SortType(), WID_VL_SORT_BY_PULLDOWN, 0,
(this->vli.vtype == VEH_TRAIN || this->vli.vtype == VEH_ROAD) ? 0 : (1 << 10));
(this->vli.vtype == VEH_TRAIN || this->vli.vtype == VEH_ROAD) ? 0 : (1 << 10), 0, DDSF_LOST_FOCUS);
return;
case WID_VL_LIST: { // Matrix to show vehicles
@ -1875,6 +1901,16 @@ struct VehicleDetailsWindow : Window {
this->tab = TDW_TAB_CARGO;
}
~VehicleDetailsWindow()
{
if (this->window_number != INVALID_VEHICLE) {
if (!FocusWindowById(WC_VEHICLE_VIEW, this->window_number)) {
if (this->window_number != INVALID_VEHICLE) MarkAllRoutePathsDirty(Vehicle::Get(this->window_number));
MarkAllRouteStepsDirty(this);
}
}
}
/**
* Some data on this window has become invalid.
* @param data Information about the changed data.
@ -2173,7 +2209,7 @@ struct VehicleDetailsWindow : Window {
case WID_VD_SERVICE_INTERVAL_DROPDOWN: {
const Vehicle *v = Vehicle::Get(this->window_number);
ShowDropDownMenu(this, _service_interval_dropdown, v->ServiceIntervalIsCustom() ? (v->ServiceIntervalIsPercent() ? 2 : 1) : 0, widget, 0, 0);
ShowDropDownMenu(this, _service_interval_dropdown, v->ServiceIntervalIsCustom() ? (v->ServiceIntervalIsPercent() ? 2 : 1) : 0, widget, 0, 0, 0, DDSF_LOST_FOCUS);
break;
}
@ -2223,6 +2259,22 @@ struct VehicleDetailsWindow : Window {
this->vscroll->SetCapacityFromWidget(this, WID_VD_MATRIX);
}
}
virtual void OnFocus(Window *previously_focused_window)
{
if (HasFocusedVehicleChanged(this->window_number, previously_focused_window)) {
if (this->window_number != INVALID_VEHICLE) MarkAllRoutePathsDirty(Vehicle::Get(this->window_number));
MarkAllRouteStepsDirty(this);
}
}
virtual void OnFocusLost(Window *newly_focused_window)
{
if (HasFocusedVehicleChanged(this->window_number, newly_focused_window)) {
if (this->window_number != INVALID_VEHICLE) MarkAllRoutePathsDirty(Vehicle::Get(this->window_number));
MarkAllRouteStepsDirty(this);
}
}
};
/** Vehicle details window descriptor. */
@ -2495,12 +2547,30 @@ public:
~VehicleViewWindow()
{
if (this->window_number != INVALID_VEHICLE) MarkAllRoutePathsDirty(Vehicle::Get(this->window_number));
MarkAllRouteStepsDirty(this);
DeleteWindowById(WC_VEHICLE_ORDERS, this->window_number, false);
DeleteWindowById(WC_VEHICLE_REFIT, this->window_number, false);
DeleteWindowById(WC_VEHICLE_DETAILS, this->window_number, false);
DeleteWindowById(WC_VEHICLE_TIMETABLE, this->window_number, false);
}
virtual void OnFocus(Window *previously_focused_window)
{
if (HasFocusedVehicleChanged(this->window_number, previously_focused_window)) {
if (this->window_number != INVALID_VEHICLE) MarkAllRoutePathsDirty(Vehicle::Get(this->window_number));
MarkAllRouteStepsDirty(this);
}
}
virtual void OnFocusLost(Window *newly_focused_window)
{
if (HasFocusedVehicleChanged(this->window_number, newly_focused_window)) {
if (this->window_number != INVALID_VEHICLE) MarkAllRoutePathsDirty(Vehicle::Get(this->window_number));
MarkAllRouteStepsDirty(this);
}
}
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
const Vehicle *v = Vehicle::Get(this->window_number);

@ -18,6 +18,7 @@
#include "station_type.h"
#include "engine_type.h"
#include "company_type.h"
#include "widgets/dropdown_func.h"
void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order, Window *parent, bool auto_refit = false);
@ -101,4 +102,33 @@ Vehicle *CheckClickOnVehicle(const struct ViewPort *vp, int x, int y);
void DrawVehicleImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip);
/**
* Tell if the focused window concerns the specified vehicle.
* @param vid Vehicle id to check.
* @param ref_window The window to check against.
* @return True if the focused window is about specified vehicle.
*/
static inline bool HasFocusedVehicleChanged(const VehicleID vid, Window *ref_window)
{
if (ref_window) {
WindowClass wc = ref_window->window_class;
WindowNumber wn = ref_window->window_number;
if (wc == WC_DROPDOWN_MENU) GetParentWindowInfo(ref_window, wc, wn);
switch (wc) {
default:
break;
case WC_VEHICLE_DETAILS:
case WC_VEHICLE_REFIT:
case WC_VEHICLE_ORDERS:
case WC_VEHICLE_TIMETABLE:
case WC_VEHICLE_VIEW:
return ((uint32) wn != vid);
}
}
return true;
}
#endif /* VEHICLE_GUI_H */

File diff suppressed because it is too large Load Diff

@ -17,6 +17,7 @@
#include "window_type.h"
#include "tile_type.h"
#include "station_type.h"
#include "vehicle_base.h"
static const int TILE_HEIGHT_STEP = 50; ///< One Z unit tile height difference is displayed as 50m.
@ -28,7 +29,11 @@ ViewPort *IsPtInWindowViewport(const Window *w, int x, int y);
Point GetTileBelowCursor();
void UpdateViewportPosition(Window *w);
void MarkAllViewportsDirty(int left, int top, int right, int bottom);
void MarkAllViewportsDirty(int left, int top, int right, int bottom, const ZoomLevel mark_dirty_if_zoomlevel_is_below = ZOOM_LVL_END);
void MarkAllViewportMapsDirty(int left, int top, int right, int bottom);
void MarkAllRouteStepsDirty(Window *vehicle_window);
void MarkTileLineDirty(const TileIndex from_tile, const TileIndex to_tile);
void MarkAllRoutePathsDirty(const Vehicle *veh);
bool DoZoomInOutWindow(ZoomStateChange how, Window *w);
void ZoomInOrOutToCursorWindow(bool in, Window * w);
@ -58,6 +63,7 @@ void ViewportAddString(const DrawPixelInfo *dpi, ZoomLevel small_from, const Vie
void StartSpriteCombine();
void EndSpriteCombine();
bool HandleViewportDoubleClicked(Window *w, int x, int y);
bool HandleViewportClicked(const ViewPort *vp, int x, int y);
void SetRedErrorSquare(TileIndex tile);
void SetTileSelectSize(int w, int h);
@ -77,11 +83,15 @@ void UpdateAllVirtCoords();
extern Point _tile_fract_coords;
void MarkTileDirtyByTile(TileIndex tile);
void MarkTileDirtyByTile(const TileIndex tile, const ZoomLevel mark_dirty_if_zoomlevel_is_below = ZOOM_LVL_END);
int GetRowAtTile(int viewport_y, Point tile, bool bridge_correct);
void MarkTileDirtyByTileOutsideMap(int x, int y);
ViewportMapType ChangeRenderMode(const ViewPort *vp, bool down);
Point GetViewportStationMiddle(const ViewPort *vp, const Station *st);
void ShowTooltipForTile(Window *w, const TileIndex tile);
#endif /* VIEWPORT_FUNC_H */

@ -16,6 +16,9 @@
#include "strings_func.h"
#include "zoom_func.h"
#include "window_func.h"
#include "gfx_func.h"
#include "industry.h"
#include "town_map.h"
#include "widgets/viewport_widget.h"
@ -78,6 +81,7 @@ public:
this->viewport->scrollpos_y = pt.y - this->viewport->virtual_height / 2;
this->viewport->dest_scrollpos_x = this->viewport->scrollpos_x;
this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y;
this->viewport->map_type = (ViewportMapType) _settings_client.gui.default_viewport_map_mode;
}
virtual void SetStringParameters(int widget) const
@ -138,10 +142,24 @@ public:
virtual void OnMouseWheel(int wheel)
{
if (_settings_client.gui.scrollwheel_scrolling == 0) {
if (_ctrl_pressed) {
/* Cycle through the drawing modes */
this->viewport->map_type = ChangeRenderMode(this->viewport, wheel < 0);
this->SetDirty();
} else if (_settings_client.gui.scrollwheel_scrolling == 0) {
ZoomInOrOutToCursorWindow(wheel < 0, this);
}
}
virtual void OnMouseOver(Point pt, int widget)
{
if (pt.x != -1) {
/* Show tooltip with last month production or town name */
const Point p = GetTileBelowCursor();
const TileIndex tile = TileVirtXY(p.x, p.y);
if (tile < MapSize()) ShowTooltipForTile(this, tile);
}
}
/**
* Some data on this window has become invalid.
@ -189,3 +207,38 @@ void ShowExtraViewPortWindowForTileUnderCursor()
Point pt = GetTileBelowCursor();
ShowExtraViewPortWindow(pt.x != -1 ? TileVirtXY(pt.x, pt.y) : INVALID_TILE);
}
void ShowTooltipForTile(Window *w, const TileIndex tile)
{
switch (GetTileType(tile)) {
case MP_ROAD:
if (IsRoadDepot(tile)) return;
/* FALL THROUGH */
case MP_HOUSE: {
if (HasBit(_display_opt, DO_SHOW_TOWN_NAMES)) return; // No need for a town name tooltip when it is already displayed
SetDParam(0, GetTownIndex(tile));
GuiShowTooltips(w, STR_TOWN_NAME_TOOLTIP, 0, NULL, TCC_HOVER);
break;
}
case MP_INDUSTRY: {
const Industry *ind = Industry::GetByTile(tile);
const IndustrySpec *indsp = GetIndustrySpec(ind->type);
StringID str = STR_INDUSTRY_VIEW_TRANSPORTED_TOOLTIP;
uint prm_count = 0;
SetDParam(prm_count++, indsp->name);
for (byte i = 0; i < lengthof(ind->produced_cargo); i++) {
if (ind->produced_cargo[i] != CT_INVALID) {
SetDParam(prm_count++, ind->produced_cargo[i]);
SetDParam(prm_count++, ind->last_month_production[i]);
SetDParam(prm_count++, ToPercent8(ind->last_month_pct_transported[i]));
str++;
}
}
GuiShowTooltips(w, str, 0, NULL, TCC_HOVER);
break;
}
default:
return;
}
}

@ -17,6 +17,17 @@
class LinkGraphOverlay;
enum ViewportMapType {
VPMT_BEGIN = 0,
VPMT_VEGETATION = 0,
VPMT_OWNER,
VPMT_INDUSTRY,
VPMT_END,
VPMT_MIN = VPMT_VEGETATION,
VPMT_MAX = VPMT_INDUSTRY,
};
/**
* Data structure for viewport, display of a part of the world
*/
@ -31,7 +42,9 @@ struct ViewPort {
int virtual_width; ///< width << zoom
int virtual_height; ///< height << zoom
ZoomLevel zoom; ///< The zoom level of the viewport.
ZoomLevel zoom; ///< The zoom level of the viewport.
ViewportMapType map_type; ///< Rendering type
LinkGraphOverlay *overlay;
};
@ -104,6 +117,7 @@ enum ViewportDragDropSelectionProcess {
DDSP_CREATE_RIVER, ///< Create rivers
DDSP_PLANT_TREES, ///< Plant trees
DDSP_BUILD_BRIDGE, ///< Bridge placement
DDSP_DRAW_PLANLINE, ///< Draw a line for a plan
/* Rail specific actions */
DDSP_PLACE_RAIL, ///< Rail placement

@ -1128,7 +1128,7 @@ static void DoDryUp(TileIndex tile)
case MP_TREES:
SetTreeGroundDensity(tile, TREE_GROUND_GRASS, 3);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
break;
case MP_WATER:

@ -266,7 +266,7 @@ CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint
MakeRailWaypoint(tile, wp->owner, wp->index, axis, layout_ptr[i], GetRailType(tile));
SetCustomStationSpecIndex(tile, map_spec_index);
SetRailStationReservation(tile, reserved);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile, ZOOM_LVL_DRAW_MAP);
DeallocateSpecFromStation(wp, old_specindex);
YapfNotifyTrackLayoutChange(tile, AxisToTrack(axis));

@ -99,6 +99,7 @@ struct DropdownWindow : Window {
int scrolling; ///< If non-zero, auto-scroll the item list (one time).
Point position; ///< Position of the topleft corner of the window.
Scrollbar *vscroll;
DropDownSyncFocus sync_parent_focus; ///< Call parent window's OnFocus[Lost]().
/**
* Create a dropdown menu.
@ -113,12 +114,15 @@ struct DropdownWindow : Window {
* @param scroll Dropdown menu has a scrollbar.
* @param widget Widgets of the dropdown menu window.
*/
DropdownWindow(Window *parent, const DropDownList *list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll)
DropdownWindow(Window *parent, const DropDownList *list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll, DropDownSyncFocus sync_parent_focus)
: Window(&_dropdown_desc)
{
assert(list->Length() > 0);
this->position = position;
this->parent_wnd_class = parent->window_class;
this->parent_wnd_num = parent->window_number;
this->sync_parent_focus = sync_parent_focus;
this->CreateNestedTree();
@ -148,8 +152,6 @@ struct DropdownWindow : Window {
this->vscroll->SetCapacity(size.height * (uint16)list->Length() / list_height);
this->vscroll->SetCount((uint16)list->Length());
this->parent_wnd_class = parent->window_class;
this->parent_wnd_num = parent->window_number;
this->parent_button = button;
this->list = list;
this->selected_index = selected;
@ -318,6 +320,22 @@ struct DropdownWindow : Window {
}
}
}
virtual void OnFocus(Window *previously_focused_window)
{
if (this->sync_parent_focus & DDSF_RECV_FOCUS) {
Window *parent = FindWindowById(this->parent_wnd_class, this->parent_wnd_num);
if (parent) parent->OnFocus(previously_focused_window);
}
}
virtual void OnFocusLost(Window *newly_focused_window)
{
if (this->sync_parent_focus & DDSF_LOST_FOCUS) {
Window *parent = FindWindowById(this->parent_wnd_class, this->parent_wnd_num);
if (parent) parent->OnFocusLost(newly_focused_window);
}
}
};
/**
@ -334,7 +352,7 @@ struct DropdownWindow : Window {
* @param instant_close Set to true if releasing mouse button should close the
* list regardless of where the cursor is.
*/
void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width, bool instant_close)
void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width, bool instant_close, DropDownSyncFocus sync_parent_focus)
{
DeleteWindowById(WC_DROPDOWN_MENU, 0);
@ -382,7 +400,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b
Point dw_pos = { w->left + (_current_text_dir == TD_RTL ? wi_rect.right + 1 - width : wi_rect.left), top};
Dimension dw_size = {width, height};
new DropdownWindow(w, list, selected, button, instant_close, dw_pos, dw_size, wi_colour, scroll);
new DropdownWindow(w, list, selected, button, instant_close, dw_pos, dw_size, wi_colour, scroll, sync_parent_focus);
}
/**
@ -398,7 +416,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b
* @param instant_close Set to true if releasing mouse button should close the
* list regardless of where the cursor is.
*/
void ShowDropDownList(Window *w, const DropDownList *list, int selected, int button, uint width, bool auto_width, bool instant_close)
void ShowDropDownList(Window *w, const DropDownList *list, int selected, int button, uint width, bool auto_width, bool instant_close, DropDownSyncFocus sync_parent_focus)
{
/* Our parent's button widget is used to determine where to place the drop
* down list window. */
@ -425,7 +443,7 @@ void ShowDropDownList(Window *w, const DropDownList *list, int selected, int but
}
}
ShowDropDownListAt(w, list, selected, button, wi_rect, wi_colour, auto_width, instant_close);
ShowDropDownListAt(w, list, selected, button, wi_rect, wi_colour, auto_width, instant_close, sync_parent_focus);
}
/**
@ -439,7 +457,7 @@ void ShowDropDownList(Window *w, const DropDownList *list, int selected, int but
* @param hidden_mask Bitmask for hidden items (items with their bit set are not copied to the dropdown list).
* @param width Width of the dropdown menu. If \c 0, use the width of parent widget \a button.
*/
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width)
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width, DropDownSyncFocus sync_parent_focus)
{
DropDownList *list = new DropDownList();
@ -455,7 +473,7 @@ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int butt
return;
}
ShowDropDownList(w, list, selected, button, width);
ShowDropDownList(w, list, selected, button, width, false, false, sync_parent_focus);
}
/**
@ -482,3 +500,10 @@ int HideDropDownMenu(Window *pw)
return -1;
}
void GetParentWindowInfo(Window *w, WindowClass &parent_wc, WindowNumber &parent_wn)
{
DropdownWindow *dw = dynamic_cast<DropdownWindow*>(w);
assert(dw != NULL);
parent_wc = dw->parent_wnd_class;
parent_wn = dw->parent_wnd_num;
}

@ -13,11 +13,14 @@
#define WIDGETS_DROPDOWN_FUNC_H
#include "../window_gui.h"
#include "dropdown_type.h"
/* Show drop down menu containing a fixed list of strings */
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width = 0);
void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width = 0, DropDownSyncFocus sync_parent_focus = DDSF_NONE);
/* Hide drop down menu of a parent window */
int HideDropDownMenu(Window *pw);
void GetParentWindowInfo(Window *w, WindowClass &parent_wc, WindowNumber &parent_wn);
#endif /* WIDGETS_DROPDOWN_FUNC_H */

@ -17,6 +17,13 @@
#include "../core/smallvec_type.hpp"
#include "table/strings.h"
enum DropDownSyncFocus {
DDSF_NONE = 0,
DDSF_RECV_FOCUS = 1,
DDSF_LOST_FOCUS = 2,
DDSF_ALL = DDSF_RECV_FOCUS | DDSF_LOST_FOCUS,
};
/**
* Base list item class from which others are derived. If placed in a list it
* will appear as a horizontal line in the menu.
@ -85,8 +92,8 @@ public:
*/
typedef AutoDeleteSmallVector<const DropDownListItem *, 4> DropDownList;
void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width = false, bool instant_close = false);
void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width = false, bool instant_close = false, DropDownSyncFocus sync_parent_focus = DDSF_NONE);
void ShowDropDownList(Window *w, const DropDownList *list, int selected, int button, uint width = 0, bool auto_width = false, bool instant_close = false);
void ShowDropDownList(Window *w, const DropDownList *list, int selected, int button, uint width = 0, bool auto_width = false, bool instant_close = false, DropDownSyncFocus sync_parent_focus = DDSF_NONE);
#endif /* WIDGETS_DROPDOWN_TYPE_H */

@ -0,0 +1,27 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file plans_widget.h Types related to the plans widgets. */
#ifndef WIDGETS_PLANS_WIDGET_H
#define WIDGETS_PLANS_WIDGET_H
/** Widgets of the #PlansWindow class. */
enum PlansWidgets {
WID_PLN_CAPTION, ///< Caption of the window.
WID_PLN_LIST,
WID_PLN_SCROLLBAR,
WID_PLN_NEW,
WID_PLN_ADD_LINES,
WID_PLN_VISIBILITY,
WID_PLN_HIDE_ALL,
WID_PLN_DELETE,
};
#endif /* WIDGETS_PLANS_WIDGET_H */

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save