29 #include "table/strings.h"
52 #define MK(a, b) {a, b, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, false, false}
55 #define MC(col_break) {0, STR_TINY_BLACK_HEIGHT, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, false, col_break}
58 #define MO(a, b) {a, b, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, false, false}
61 #define MOEND() {0, 0, INVALID_INDUSTRYTYPE, 0, OWNER_NONE, true, true, false}
64 #define MKEND() {0, STR_NULL, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, true, false}
70 #define MS(a, b) {a, b, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, false, true}
75 MK(
PC_GREY, STR_SMALLMAP_LEGENDA_RAILROADS),
99 MK(
PC_RED, STR_SMALLMAP_LEGENDA_TRAINS),
104 MS(
PC_BLACK, STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES),
111 MK(
PC_GREY, STR_SMALLMAP_LEGENDA_RAILROADS),
115 MK(
PC_ORANGE, STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY),
117 MK(
PC_RED, STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT),
133 MK(
PC_BLACK, STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES),
140 MO(0x00, STR_SMALLMAP_LEGENDA_NO_OWNER),
184 _legend_from_industries[j].
legend = indsp->
name;
186 _legend_from_industries[j].
type = ind;
188 _legend_from_industries[j].
col_break =
false;
189 _legend_from_industries[j].
end =
false;
197 _legend_from_industries[j].
end =
true;
209 memset(_legend_linkstats, 0,
sizeof(_legend_linkstats));
216 _legend_linkstats[i].
colour = cs->legend_colour;
225 _legend_linkstats[i].
legend = STR_EMPTY;
231 _legend_linkstats[i - 1].
legend = STR_LINKGRAPH_LEGEND_OVERLOADED;
233 _legend_linkstats[i].
end =
true;
246 #define MKCOLOUR(x) TO_LE32X(x)
248 #define MKCOLOUR_XXXX(x) (MKCOLOUR(0x01010101) * (uint)(x))
249 #define MKCOLOUR_X0X0(x) (MKCOLOUR(0x01000100) * (uint)(x))
250 #define MKCOLOUR_0X0X(x) (MKCOLOUR(0x00010001) * (uint)(x))
251 #define MKCOLOUR_0XX0(x) (MKCOLOUR(0x00010100) * (uint)(x))
252 #define MKCOLOUR_X00X(x) (MKCOLOUR(0x01000001) * (uint)(x))
254 #define MKCOLOUR_XYXY(x, y) (MKCOLOUR_X0X0(x) | MKCOLOUR_0X0X(y))
255 #define MKCOLOUR_XYYX(x, y) (MKCOLOUR_X00X(x) | MKCOLOUR_0XX0(y))
257 #define MKCOLOUR_0000 MKCOLOUR_XXXX(0x00)
258 #define MKCOLOUR_0FF0 MKCOLOUR_0XX0(0xFF)
259 #define MKCOLOUR_F00F MKCOLOUR_X00X(0xFF)
260 #define MKCOLOUR_FFFF MKCOLOUR_XXXX(0xFF)
285 if (_heightmap_schemes[0].height_colours == NULL)
return;
307 uint deltas[][2] = { { 24, 2 }, { 48, 4 }, { 72, 6 }, { 120, 10 }, { 180, 15 }, { 240, 20 }, {
MAX_TILE_HEIGHT + 1, 25 }};
312 uint delta = deltas[i][1];
315 int rows =
CeilDiv(total_entries, 2);
318 for (i = 0; i <
lengthof(_legend_land_contours) - 1 && j < total_entries; i++) {
319 if (_legend_land_contours[i].legend != STR_TINY_BLACK_HEIGHT)
continue;
321 _legend_land_contours[i].
col_break = j % rows == 0;
322 _legend_land_contours[i].
end =
false;
323 _legend_land_contours[i].
height = j * delta;
327 _legend_land_contours[i].
end =
true;
339 FOR_ALL_COMPANIES(c) {
343 _legend_land_owners[i].
col_break =
false;
344 _legend_land_owners[i].
end =
false;
350 _legend_land_owners[i].
end =
true;
361 static inline uint32 ApplyMask(uint32 colour,
const AndOr *mask)
363 return (colour & mask->mand) | mask->mor;
369 {MKCOLOUR_0000 , MKCOLOUR_FFFF},
370 {MKCOLOUR_0XX0(
PC_GREY ), MKCOLOUR_F00F},
371 {MKCOLOUR_0XX0(
PC_BLACK ), MKCOLOUR_F00F},
373 {MKCOLOUR_0000 , MKCOLOUR_FFFF},
375 {MKCOLOUR_XXXX(
PC_WATER ), MKCOLOUR_0000},
376 {MKCOLOUR_0000 , MKCOLOUR_FFFF},
378 {MKCOLOUR_0000 , MKCOLOUR_FFFF},
380 {MKCOLOUR_0XX0(
PC_GREY ), MKCOLOUR_F00F},
385 {MKCOLOUR_0000 , MKCOLOUR_FFFF},
386 {MKCOLOUR_0XX0(
PC_BLACK ), MKCOLOUR_F00F},
387 {MKCOLOUR_0XX0(
PC_BLACK ), MKCOLOUR_F00F},
389 {MKCOLOUR_0000 , MKCOLOUR_FFFF},
390 {MKCOLOUR_0XX0(
PC_BLACK ), MKCOLOUR_F00F},
391 {MKCOLOUR_XXXX(
PC_WATER ), MKCOLOUR_0000},
392 {MKCOLOUR_0000 , MKCOLOUR_FFFF},
394 {MKCOLOUR_0000 , MKCOLOUR_FFFF},
396 {MKCOLOUR_0XX0(
PC_BLACK ), MKCOLOUR_F00F},
454 return ApplyMask(cs->
default_colour, &_smallmap_vehicles_andor[t]);
494 case STATION_AIRPORT:
return MKCOLOUR_XXXX(
PC_RED);
495 case STATION_TRUCK:
return MKCOLOUR_XXXX(
PC_ORANGE);
496 case STATION_BUS:
return MKCOLOUR_XXXX(
PC_YELLOW);
498 default:
return MKCOLOUR_FFFF;
503 _smallmap_contours_andor[t].mand
512 return ApplyMask(cs->
default_colour, &_smallmap_contours_andor[t]);
527 static const uint32 _vegetation_clear_bits[] = {
561 return ApplyMask(MKCOLOUR_XXXX(
PC_GRASS_LAND), &_smallmap_vehicles_andor[t]);
603 inline Point SmallMapWindow::SmallmapRemapCoords(
int x,
int y)
const
622 if (this->
zoom == 1)
return SmallmapRemapCoords(x_offset, y_offset);
625 if (x_offset < 0) x_offset -= this->
zoom - 1;
626 if (y_offset < 0) y_offset -= this->
zoom - 1;
628 return SmallmapRemapCoords(x_offset / this->
zoom, y_offset / this->
zoom);
647 Point pt = {((py >> 1) - (px >> 2)) * this->
zoom, ((py >> 1) + (px >> 2)) * this->
zoom};
675 assert(x >= 0 && y >= 0);
703 static const int zoomlevels[] = {1, 2, 4, 6, 8};
704 static const int MIN_ZOOM_INDEX = 0;
705 static const int MAX_ZOOM_INDEX =
lengthof(zoomlevels) - 1;
707 int new_index, cur_index, sub;
712 new_index = MIN_ZOOM_INDEX;
718 for (cur_index = MIN_ZOOM_INDEX; cur_index <= MAX_ZOOM_INDEX; cur_index++) {
719 if (this->
zoom == zoomlevels[cur_index])
break;
721 assert(cur_index <= MAX_ZOOM_INDEX);
723 tile = this->
PixelToTile(zoom_pt->x, zoom_pt->y, &sub);
724 new_index =
Clamp(cur_index + ((change ==
ZLC_ZOOM_IN) ? -1 : 1), MIN_ZOOM_INDEX, MAX_ZOOM_INDEX);
727 default: NOT_REACHED();
730 if (new_index != cur_index) {
731 this->
zoom = zoomlevels[new_index];
732 if (cur_index >= 0) {
735 this->scroll_y + (tile.y - new_tile.y) *
TILE_SIZE, sub);
736 }
else if (this->
map_type == SMT_LINKSTATS) {
757 TileType ttype = GetEffectiveTileType(ti);
758 if (_tiletype_importance[ttype] > importance) {
759 importance = _tiletype_importance[ttype];
787 default: NOT_REACHED();
806 void *dst_ptr_abs_end = blitter->
MoveTo(_screen.dst_ptr, 0, _screen.height);
814 if (dst < _screen.dst_ptr)
continue;
815 if (dst >= dst_ptr_abs_end)
continue;
819 if (min_xy == 1 && (xc == 0 || yc == 0)) {
820 if (this->
zoom == 1)
continue;
829 uint8 *val8 = (uint8 *)&val;
830 int idx =
max(0, -start_pos);
831 for (
int pos =
max(0, start_pos); pos < end_pos; pos++) {
832 blitter->
SetPixel(dst, idx, 0, val8[idx]);
836 }
while (xc += this->
zoom, yc += this->
zoom, dst = blitter->
MoveTo(dst, pitch, 0), --reps != 0);
854 int y = pt.y - dpi->top;
858 int x = pt.x - this->
subscroll - 3 - dpi->left;
862 if (++x != 0)
continue;
864 }
else if (x >= dpi->width - 1) {
866 if (x != dpi->width - 1)
continue;
874 blitter->
SetPixel(dpi->dst_ptr, x, y, colour);
875 if (!skip) blitter->
SetPixel(dpi->dst_ptr, x + 1, y, colour);
894 x < dpi->
left + dpi->width &&
896 y < dpi->
top + dpi->height) {
915 Point upper_left = this->
RemapTile(upper_left_smallmap_coord.x / (
int)
TILE_SIZE, upper_left_smallmap_coord.y / (
int)TILE_SIZE);
918 Point lower_right = this->
RemapTile(lower_right_smallmap_coord.x / (
int)TILE_SIZE, lower_right_smallmap_coord.y / (
int)TILE_SIZE);
948 GfxFillRect(dpi->left, dpi->top, dpi->left + dpi->width - 1, dpi->top + dpi->height - 1,
PC_BLACK);
954 int tile_y = this->scroll_y / (
int)
TILE_SIZE + tile.y;
956 void *ptr = blitter->
MoveTo(dpi->dst_ptr, -dx - 4, 0);
963 if (x >= dpi->width)
break;
965 int end_pos =
min(dpi->width, x + 4);
966 int reps = (dpi->height - y + 1) / 2;
968 this->
DrawSmallMapColumn(ptr, tile_x, tile_y, dpi->pitch * 2, reps, x, end_pos, blitter);
973 tile_y += this->
zoom;
975 ptr = blitter->
MoveTo(ptr, 0, 1);
977 tile_x -= this->
zoom;
979 ptr = blitter->
MoveTo(ptr, 0, -1);
981 ptr = blitter->
MoveTo(ptr, 2, 0);
989 if (this->
map_type == SMT_LINKSTATS) this->overlay->
Draw(dpi);
1011 legend_tooltip = STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION;
1012 enable_all_tooltip = STR_SMALLMAP_TOOLTIP_ENABLE_ALL_INDUSTRIES;
1013 disable_all_tooltip = STR_SMALLMAP_TOOLTIP_DISABLE_ALL_INDUSTRIES;
1018 legend_tooltip = STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION;
1019 enable_all_tooltip = STR_SMALLMAP_TOOLTIP_ENABLE_ALL_COMPANIES;
1020 disable_all_tooltip = STR_SMALLMAP_TOOLTIP_DISABLE_ALL_COMPANIES;
1025 legend_tooltip = STR_SMALLMAP_TOOLTIP_CARGO_SELECTION;
1026 enable_all_tooltip = STR_SMALLMAP_TOOLTIP_ENABLE_ALL_CARGOS;
1027 disable_all_tooltip = STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS;
1032 legend_tooltip = STR_NULL;
1033 enable_all_tooltip = STR_NULL;
1034 disable_all_tooltip = STR_NULL;
1045 SmallMapWindow::SmallMapWindow(
WindowDesc *desc,
int window_number) :
Window(desc), refresh(FORCE_REFRESH_PERIOD)
1073 for (uint n = 0; n <
lengthof(_heightmap_schemes); n++) {
1078 for (
int z = 0; z < heights; z++) {
1079 size_t access_index = (_heightmap_schemes[n].
colour_count * z) / heights;
1104 for (uint i = 0; i <
lengthof(_legend_table); i++) {
1106 uint num_columns = 1;
1109 if (i == SMT_INDUSTRY) {
1112 str = STR_SMALLMAP_INDUSTRY;
1113 }
else if (i == SMT_LINKSTATS) {
1115 str = STR_SMALLMAP_LINKSTATS;
1116 }
else if (i == SMT_OWNER) {
1126 str = STR_SMALLMAP_COMPANY;
1131 if (tbl->col_break) {
1170 if (!
FillDrawPixelInfo(&new_dpi, r.left + 1, r.top + 1, r.right - r.left - 1, r.bottom - r.top - 1))
return;
1193 string = STR_SMALLMAP_INDUSTRY;
1196 string = STR_SMALLMAP_LINKSTATS;
1199 string = STR_SMALLMAP_COMPANY;
1206 if (tbl->col_break || ((this->map_type == SMT_INDUSTRY || this->map_type == SMT_OWNER || this->map_type == SMT_LINKSTATS) && i++ >= number_of_rows)) {
1214 uint8 legend_colour = tbl->colour;
1232 if (!tbl->show_on_map) {
1235 DrawString(x + text_left, x + text_right, y,
string, TC_GREY);
1237 DrawString(x + text_left, x + text_right, y,
string, TC_BLACK);
1247 DrawString(x + text_left, x + text_right, y, tbl->legend);
1250 GfxFillRect(x + blob_left + 1, y + 2, x + blob_right - 1, y + row_height - 2, legend_colour);
1270 if (map_type == SMT_LINKSTATS) this->overlay->
RebuildCache();
1305 bool changes =
false;
1306 for (
int i = begin_legend_item; i != end_legend_item; i++) {
1307 bool new_state = (i == click_pos);
1308 if (legend[i].show_on_map != new_state) {
1315 for (
int i = begin_legend_item; i != end_legend_item; i++) {
1329 uint32 cargo_mask = 0;
1331 if (_legend_linkstats[i].show_on_map)
SetBit(cargo_mask, _legend_linkstats[i].type);
1347 if (line >= number_of_rows)
return -1;
1350 int x = pt.x - wi->
pos_x;
1354 return (column * number_of_rows) + line;
1363 new_highlight = _legend_from_industries[industry_pos].
type;
1438 if (click_pos < 0)
break;
1441 if (this->
map_type == SMT_INDUSTRY) {
1446 }
else if (this->
map_type == SMT_LINKSTATS) {
1451 }
else if (this->
map_type == SMT_OWNER) {
1477 for (;!tbl->
end && tbl->
legend != STR_LINKGRAPH_LEGEND_UNUSED; ++tbl) {
1503 if (!gui_scope)
return;
1516 _legend_from_industries[i].
show_on_map = _displayed_industries.test(_legend_from_industries[i].type);
1525 default: NOT_REACHED();
1542 int cursor_x = _cursor.pos.x - this->
left - wid->
pos_x;
1543 int cursor_y = _cursor.pos.y - this->
top - wid->
pos_y;
1545 Point pt = {cursor_x, cursor_y};
1554 if (--this->
refresh != 0)
return;
1556 if (this->
map_type == SMT_LINKSTATS) {
1642 int x = (st->
rect.right + st->
rect.left + 1) / 2;
1643 int y = (st->
rect.bottom + st->
rect.top + 1) / 2;
1709 uint bar_height =
max(bar->
smallest_y, this->smallmap_window->GetLegendHeight(this->smallmap_window->GetNumberColumnsLegend(given_width - bar->
smallest_x)));
1710 uint display_height = given_height - bar_height;
1718 for (
NWidgetBase *child_wid = this->
head; child_wid != NULL; child_wid = child_wid->
next) {
1720 if (widget != NULL)
return widget;
1727 for (
NWidgetBase *child_wid = this->
head; child_wid != NULL; child_wid = child_wid->
next) child_wid->Draw(w);
1734 NWidget(
WWT_INSET, COLOUR_BROWN,
WID_SM_MAP),
SetMinimalSize(346, 140),
SetResize(1, 1),
SetPadding(2, 2, 2, 2),
EndContainer(),
1747 SetDataTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN),
SetFill(1, 1),
1753 SetDataTip(SPR_IMG_SHOW_COUNTOURS, STR_SMALLMAP_TOOLTIP_SHOW_LAND_CONTOURS_ON_MAP),
SetFill(1, 1),
1755 SetDataTip(SPR_IMG_SHOW_VEHICLES, STR_SMALLMAP_TOOLTIP_SHOW_VEHICLES_ON_MAP),
SetFill(1, 1),
1757 SetDataTip(SPR_IMG_INDUSTRY, STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP),
SetFill(1, 1),
1762 SetDataTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT),
SetFill(1, 1),
1764 SetDataTip(SPR_IMG_TOWN, STR_SMALLMAP_TOOLTIP_TOGGLE_TOWN_NAMES_ON_OFF),
SetFill(1, 1),
1766 SetDataTip(SPR_IMG_CARGOFLOW, STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP),
SetFill(1, 1),
1768 SetDataTip(SPR_IMG_SHOW_ROUTES, STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON),
SetFill(1, 1),
1770 SetDataTip(SPR_IMG_PLANTTREES, STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP),
SetFill(1, 1),
1772 SetDataTip(SPR_IMG_COMPANY_GENERAL, STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP),
SetFill(1, 1),
1780 static NWidgetBase *SmallMapDisplay(
int *biggest_index)
1784 MakeNWidgets(_nested_smallmap_display,
lengthof(_nested_smallmap_display), biggest_index, map_display);
1785 MakeNWidgets(_nested_smallmap_bar,
lengthof(_nested_smallmap_bar), biggest_index, map_display);
1790 static const NWidgetPart _nested_smallmap_widgets[] = {
1820 _nested_smallmap_widgets,
lengthof(_nested_smallmap_widgets)
1828 AllocateWindowDescFront<SmallMapWindow>(&_smallmap_desc, 0);
1847 if (res)
return res;