24 #include "train.h" |
25 #include "train.h" |
25 #include "table/station_air.h" |
26 #include "table/station_air.h" |
26 |
27 |
27 #define VIEWPORT_DRAW_MEM (65536 * 2) |
28 #define VIEWPORT_DRAW_MEM (65536 * 2) |
28 |
29 |
29 // XXX - maximum viewports is maximum windows - 2 (main toolbar + status bar) |
30 ZoomLevel _saved_scrollpos_zoom; |
|
31 |
|
32 /* XXX - maximum viewports is maximum windows - 2 (main toolbar + status bar) */ |
30 static ViewPort _viewports[25 - 2]; |
33 static ViewPort _viewports[25 - 2]; |
31 static uint32 _active_viewports; ///< bitmasked variable where each bit signifies if a viewport is in use or not |
34 static uint32 _active_viewports; ///< bitmasked variable where each bit signifies if a viewport is in use or not |
32 assert_compile(lengthof(_viewports) < sizeof(_active_viewports) * 8); |
35 assert_compile(lengthof(_viewports) < sizeof(_active_viewports) * 8); |
33 |
36 |
34 static bool _added_tile_sprite; |
37 static bool _added_tile_sprite; |
179 pt = MapXYZToViewport(vp, x, y, GetSlopeZ(x, y)); |
182 pt = MapXYZToViewport(vp, x, y, GetSlopeZ(x, y)); |
180 } |
183 } |
181 |
184 |
182 WP(w, vp_d).scrollpos_x = pt.x; |
185 WP(w, vp_d).scrollpos_x = pt.x; |
183 WP(w, vp_d).scrollpos_y = pt.y; |
186 WP(w, vp_d).scrollpos_y = pt.y; |
|
187 WP(w, vp_d).dest_scrollpos_x = pt.x; |
|
188 WP(w, vp_d).dest_scrollpos_y = pt.y; |
|
189 |
184 w->viewport = vp; |
190 w->viewport = vp; |
185 vp->virtual_left = 0;//pt.x; |
191 vp->virtual_left = 0;//pt.x; |
186 vp->virtual_top = 0;//pt.y; |
192 vp->virtual_top = 0;//pt.y; |
187 } |
193 } |
188 |
194 |
265 int left, top, width, height; |
271 int left, top, width, height; |
266 |
272 |
267 vp->virtual_left = x; |
273 vp->virtual_left = x; |
268 vp->virtual_top = y; |
274 vp->virtual_top = y; |
269 |
275 |
270 old_left >>= vp->zoom; |
276 old_left = UnScaleByZoom(old_left, vp->zoom); |
271 old_top >>= vp->zoom; |
277 old_top = UnScaleByZoom(old_top, vp->zoom); |
272 x >>= vp->zoom; |
278 x = UnScaleByZoom(x, vp->zoom); |
273 y >>= vp->zoom; |
279 y = UnScaleByZoom(y, vp->zoom); |
274 |
280 |
275 old_left -= x; |
281 old_left -= x; |
276 old_top -= y; |
282 old_top -= y; |
277 |
283 |
278 if (old_top == 0 && old_left == 0) return; |
284 if (old_top == 0 && old_left == 0) return; |
396 return GetTileFromScreenXY(_cursor.pos.x, _cursor.pos.y, x + vp->left, y + vp->top); |
402 return GetTileFromScreenXY(_cursor.pos.x, _cursor.pos.y, x + vp->left, y + vp->top); |
397 } |
403 } |
398 |
404 |
399 /** Update the status of the zoom-buttons according to the zoom-level |
405 /** Update the status of the zoom-buttons according to the zoom-level |
400 * of the viewport. This will update their status and invalidate accordingly |
406 * of the viewport. This will update their status and invalidate accordingly |
401 * @param window pointer to the window that has the zoom buttons |
407 * @param w Window pointer to the window that has the zoom buttons |
402 * @param vp pointer to the viewport whose zoom-level the buttons represent |
408 * @param vp pointer to the viewport whose zoom-level the buttons represent |
403 * @param widget_zoom_in widget index for window with zoom-in button |
409 * @param widget_zoom_in widget index for window with zoom-in button |
404 * @param widget_zoom_out widget index for window with zoom-out button */ |
410 * @param widget_zoom_out widget index for window with zoom-out button */ |
405 void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte widget_zoom_out) |
411 void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte widget_zoom_out) |
406 { |
412 { |
407 SetWindowWidgetDisabledState(w, widget_zoom_in, vp->zoom == 0); |
413 SetWindowWidgetDisabledState(w, widget_zoom_in, vp->zoom == ZOOM_LVL_MIN); |
408 InvalidateWidget(w, widget_zoom_in); |
414 InvalidateWidget(w, widget_zoom_in); |
409 |
415 |
410 SetWindowWidgetDisabledState(w, widget_zoom_out, vp->zoom == 2); |
416 SetWindowWidgetDisabledState(w, widget_zoom_out, vp->zoom == ZOOM_LVL_MAX); |
411 InvalidateWidget(w, widget_zoom_out); |
417 InvalidateWidget(w, widget_zoom_out); |
412 } |
418 } |
413 |
419 |
414 void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z) |
420 void DrawGroundSpriteAt(SpriteID image, SpriteID pal, int32 x, int32 y, byte z) |
415 { |
421 { |
437 } |
443 } |
438 |
444 |
439 void DrawGroundSprite(SpriteID image, SpriteID pal) |
445 void DrawGroundSprite(SpriteID image, SpriteID pal) |
440 { |
446 { |
441 if (_offset_ground_sprites) { |
447 if (_offset_ground_sprites) { |
442 // offset ground sprite because of foundation? |
448 /* offset ground sprite because of foundation? */ |
443 AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y); |
449 AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y); |
444 } else { |
450 } else { |
445 _added_tile_sprite = true; |
451 _added_tile_sprite = true; |
446 DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z); |
452 DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z); |
447 } |
453 } |
492 return; |
498 return; |
493 } |
499 } |
494 ps = (ParentSpriteToDraw*)vd->spritelist_mem; |
500 ps = (ParentSpriteToDraw*)vd->spritelist_mem; |
495 |
501 |
496 if (vd->parent_list >= vd->eof_parent_list) { |
502 if (vd->parent_list >= vd->eof_parent_list) { |
497 // This can happen rarely, mostly when you zoom out completely |
503 /* This can happen rarely, mostly when you zoom out completely |
498 // and have a lot of stuff that moves (and is added to the |
504 * and have a lot of stuff that moves (and is added to the |
499 // sort-list, this function). To solve it, increase |
505 * sort-list, this function). To solve it, increase |
500 // parent_list somewhere below to a higher number. |
506 * parent_list somewhere below to a higher number. |
501 // This can not really hurt you, it just gives some black |
507 * This can not really hurt you, it just gives some black |
502 // spots on the screen ;) |
508 * spots on the screen ;) */ |
503 DEBUG(sprite, 0, "Out of sprite memory (parent_list)"); |
509 DEBUG(sprite, 0, "Out of sprite memory (parent_list)"); |
504 return; |
510 return; |
505 } |
511 } |
506 |
512 |
507 pt = RemapCoords(x, y, z); |
513 pt = RemapCoords(x, y, z); |
645 static void DrawTileSelection(const TileInfo *ti) |
651 static void DrawTileSelection(const TileInfo *ti) |
646 { |
652 { |
647 SpriteID image; |
653 SpriteID image; |
648 SpriteID pal; |
654 SpriteID pal; |
649 |
655 |
650 // Draw a red error square? |
656 /* Draw a red error square? */ |
651 if (_thd.redsq != 0 && _thd.redsq == ti->tile) { |
657 if (_thd.redsq != 0 && _thd.redsq == ti->tile) { |
652 DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_TILE_RED_PULSATING, ti); |
658 DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_TILE_RED_PULSATING, ti); |
653 return; |
659 return; |
654 } |
660 } |
655 |
661 |
656 // no selection active? |
662 /* no selection active? */ |
657 if (_thd.drawstyle == 0) return; |
663 if (_thd.drawstyle == 0) return; |
658 |
664 |
659 // Inside the inner area? |
665 /* Inside the inner area? */ |
660 if (IS_INSIDE_1D(ti->x, _thd.pos.x, _thd.size.x) && |
666 if (IS_INSIDE_1D(ti->x, _thd.pos.x, _thd.size.x) && |
661 IS_INSIDE_1D(ti->y, _thd.pos.y, _thd.size.y)) { |
667 IS_INSIDE_1D(ti->y, _thd.pos.y, _thd.size.y)) { |
662 if (_thd.drawstyle & HT_RECT) { |
668 if (_thd.drawstyle & HT_RECT) { |
663 if ((_thd.airport_template) && |
669 if ((_thd.airport_template) && |
664 ((byte)(_airport_sections[_thd.airport][((ti->x - _thd.pos.x) / TILE_SIZE ) + ((ti->y - _thd.pos.y) / TILE_SIZE * _thd.size.x / TILE_SIZE)]) != 255)) { |
670 ((byte)(_airport_sections[_thd.airport][((ti->x - _thd.pos.x) / TILE_SIZE ) + ((ti->y - _thd.pos.y) / TILE_SIZE * _thd.size.x / TILE_SIZE)]) != 255)) { |
667 } else if (!_thd.airport_template) { |
673 } else if (!_thd.airport_template) { |
668 image = SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh]; |
674 image = SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh]; |
669 DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE, ti); |
675 DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE, ti); |
670 } |
676 } |
671 } else if (_thd.drawstyle & HT_POINT) { |
677 } else if (_thd.drawstyle & HT_POINT) { |
672 // Figure out the Z coordinate for the single dot. |
678 /* Figure out the Z coordinate for the single dot. */ |
673 byte z = ti->z; |
679 byte z = ti->z; |
674 if (ti->tileh & SLOPE_N) { |
680 if (ti->tileh & SLOPE_N) { |
675 z += TILE_HEIGHT; |
681 z += TILE_HEIGHT; |
676 if (ti->tileh == SLOPE_STEEP_N) z += TILE_HEIGHT; |
682 if (ti->tileh == SLOPE_STEEP_N) z += TILE_HEIGHT; |
677 } |
683 } |
678 DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti->x, ti->y, z); |
684 DrawGroundSpriteAt(_cur_dpi->zoom <= ZOOM_LVL_DETAIL ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti->x, ti->y, z); |
679 } else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) { |
685 } else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) { |
680 // autorail highlight piece under cursor |
686 /* autorail highlight piece under cursor */ |
681 uint type = _thd.drawstyle & 0xF; |
687 uint type = _thd.drawstyle & 0xF; |
682 int offset; |
688 int offset; |
683 |
689 |
684 assert(type <= 5); |
690 assert(type <= 5); |
685 |
691 |
719 DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti); |
725 DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti); |
720 } |
726 } |
721 return; |
727 return; |
722 } |
728 } |
723 |
729 |
724 // Check if it's inside the outer area? |
730 /* Check if it's inside the outer area? */ |
725 if (_thd.outersize.x && |
731 if (_thd.outersize.x && |
726 _thd.size.x < _thd.size.x + _thd.outersize.x && |
732 _thd.size.x < _thd.size.x + _thd.outersize.x && |
727 IS_INSIDE_1D(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) && |
733 IS_INSIDE_1D(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) && |
728 IS_INSIDE_1D(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) { |
734 IS_INSIDE_1D(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) { |
729 // Draw a blue rect. |
735 /* Draw a blue rect. */ |
730 DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_SEL_TILE_BLUE, ti); |
736 DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_SEL_TILE_BLUE, ti); |
731 return; |
737 return; |
732 } |
738 } |
733 } |
739 } |
734 |
740 |
739 TileInfo ti; |
745 TileInfo ti; |
740 bool direction; |
746 bool direction; |
741 |
747 |
742 _cur_ti = &ti; |
748 _cur_ti = &ti; |
743 |
749 |
744 // Transform into tile coordinates and round to closest full tile |
750 /* Transform into tile coordinates and round to closest full tile */ |
745 x = ((vd->dpi.top >> 1) - (vd->dpi.left >> 2)) & ~0xF; |
751 x = ((vd->dpi.top >> 1) - (vd->dpi.left >> 2)) & ~0xF; |
746 y = ((vd->dpi.top >> 1) + (vd->dpi.left >> 2) - 0x10) & ~0xF; |
752 y = ((vd->dpi.top >> 1) + (vd->dpi.left >> 2) - 0x10) & ~0xF; |
747 |
753 |
748 // determine size of area |
754 /* determine size of area */ |
749 { |
755 { |
750 Point pt = RemapCoords(x, y, 241); |
756 Point pt = RemapCoords(x, y, 241); |
751 width = (vd->dpi.left + vd->dpi.width - pt.x + 95) >> 6; |
757 width = (vd->dpi.left + vd->dpi.width - pt.x + 95) >> 6; |
752 height = (vd->dpi.top + vd->dpi.height - pt.y) >> 5 << 1; |
758 height = (vd->dpi.top + vd->dpi.height - pt.y) >> 5 << 1; |
753 } |
759 } |
803 static void ViewportAddTownNames(DrawPixelInfo *dpi) |
809 static void ViewportAddTownNames(DrawPixelInfo *dpi) |
804 { |
810 { |
805 Town *t; |
811 Town *t; |
806 int left, top, right, bottom; |
812 int left, top, right, bottom; |
807 |
813 |
808 if (!(_display_opt & DO_SHOW_TOWN_NAMES) || _game_mode == GM_MENU) |
814 if (!HASBIT(_display_opt, DO_SHOW_TOWN_NAMES) || _game_mode == GM_MENU) |
809 return; |
815 return; |
810 |
816 |
811 left = dpi->left; |
817 left = dpi->left; |
812 top = dpi->top; |
818 top = dpi->top; |
813 right = left + dpi->width; |
819 right = left + dpi->width; |
814 bottom = top + dpi->height; |
820 bottom = top + dpi->height; |
815 |
821 |
816 switch (dpi->zoom) { |
822 switch (dpi->zoom) { |
817 case 0: |
823 case ZOOM_LVL_NORMAL: |
818 FOR_ALL_TOWNS(t) { |
824 FOR_ALL_TOWNS(t) { |
819 if (bottom > t->sign.top && |
825 if (bottom > t->sign.top && |
820 top < t->sign.top + 12 && |
826 top < t->sign.top + 12 && |
821 right > t->sign.left && |
827 right > t->sign.left && |
822 left < t->sign.left + t->sign.width_1) { |
828 left < t->sign.left + t->sign.width_1) { |
841 t->index, t->population); |
847 t->index, t->population); |
842 } |
848 } |
843 } |
849 } |
844 break; |
850 break; |
845 |
851 |
846 default: NOT_REACHED(); |
852 case ZOOM_LVL_OUT_4X: |
847 case 2: |
853 case ZOOM_LVL_OUT_8X: |
848 right += 4; |
854 right += ScaleByZoom(1, dpi->zoom); |
849 bottom += 5; |
855 bottom += ScaleByZoom(1, dpi->zoom) + 1; |
850 |
856 |
851 FOR_ALL_TOWNS(t) { |
857 FOR_ALL_TOWNS(t) { |
852 if (bottom > t->sign.top && |
858 if (bottom > t->sign.top && |
853 top < t->sign.top + 24 && |
859 top < t->sign.top + ScaleByZoom(12, dpi->zoom) && |
854 right > t->sign.left && |
860 right > t->sign.left && |
855 left < t->sign.left + t->sign.width_2*4) { |
861 left < t->sign.left + ScaleByZoom(t->sign.width_2, dpi->zoom)) { |
856 AddStringToDraw(t->sign.left + 5, t->sign.top + 1, STR_TOWN_LABEL_TINY_BLACK, t->index, 0); |
862 AddStringToDraw(t->sign.left + 5, t->sign.top + 1, STR_TOWN_LABEL_TINY_BLACK, t->index, 0); |
857 AddStringToDraw(t->sign.left + 1, t->sign.top - 3, STR_TOWN_LABEL_TINY_WHITE, t->index, 0); |
863 AddStringToDraw(t->sign.left + 1, t->sign.top - 3, STR_TOWN_LABEL_TINY_WHITE, t->index, 0); |
858 } |
864 } |
859 } |
865 } |
860 break; |
866 break; |
|
867 |
|
868 case ZOOM_LVL_OUT_16X: |
|
869 break; |
|
870 |
|
871 default: NOT_REACHED(); |
861 } |
872 } |
862 } |
873 } |
863 |
874 |
864 |
875 |
865 static void AddStation(const Station *st, StringID str, uint16 width) |
876 static void AddStation(const Station *st, StringID str, uint16 width) |
877 static void ViewportAddStationNames(DrawPixelInfo *dpi) |
888 static void ViewportAddStationNames(DrawPixelInfo *dpi) |
878 { |
889 { |
879 int left, top, right, bottom; |
890 int left, top, right, bottom; |
880 const Station *st; |
891 const Station *st; |
881 |
892 |
882 if (!(_display_opt & DO_SHOW_STATION_NAMES) || _game_mode == GM_MENU) |
893 if (!HASBIT(_display_opt, DO_SHOW_STATION_NAMES) || _game_mode == GM_MENU) |
883 return; |
894 return; |
884 |
895 |
885 left = dpi->left; |
896 left = dpi->left; |
886 top = dpi->top; |
897 top = dpi->top; |
887 right = left + dpi->width; |
898 right = left + dpi->width; |
888 bottom = top + dpi->height; |
899 bottom = top + dpi->height; |
889 |
900 |
890 switch (dpi->zoom) { |
901 switch (dpi->zoom) { |
891 case 0: |
902 case ZOOM_LVL_NORMAL: |
892 FOR_ALL_STATIONS(st) { |
903 FOR_ALL_STATIONS(st) { |
893 if (bottom > st->sign.top && |
904 if (bottom > st->sign.top && |
894 top < st->sign.top + 12 && |
905 top < st->sign.top + 12 && |
895 right > st->sign.left && |
906 right > st->sign.left && |
896 left < st->sign.left + st->sign.width_1) { |
907 left < st->sign.left + st->sign.width_1) { |
897 AddStation(st, STR_305C_0, st->sign.width_1); |
908 AddStation(st, STR_305C_0, st->sign.width_1); |
898 } |
909 } |
899 } |
910 } |
900 break; |
911 break; |
901 |
912 |
902 case 1: |
913 case ZOOM_LVL_OUT_2X: |
903 right += 2; |
914 right += 2; |
904 bottom += 2; |
915 bottom += 2; |
905 FOR_ALL_STATIONS(st) { |
916 FOR_ALL_STATIONS(st) { |
906 if (bottom > st->sign.top && |
917 if (bottom > st->sign.top && |
907 top < st->sign.top + 24 && |
918 top < st->sign.top + 24 && |
910 AddStation(st, STR_305C_0, st->sign.width_1); |
921 AddStation(st, STR_305C_0, st->sign.width_1); |
911 } |
922 } |
912 } |
923 } |
913 break; |
924 break; |
914 |
925 |
915 default: NOT_REACHED(); |
926 case ZOOM_LVL_OUT_4X: |
916 case 2: |
927 case ZOOM_LVL_OUT_8X: |
917 right += 4; |
928 right += ScaleByZoom(1, dpi->zoom); |
918 bottom += 5; |
929 bottom += ScaleByZoom(1, dpi->zoom) + 1; |
|
930 |
919 FOR_ALL_STATIONS(st) { |
931 FOR_ALL_STATIONS(st) { |
920 if (bottom > st->sign.top && |
932 if (bottom > st->sign.top && |
921 top < st->sign.top + 24 && |
933 top < st->sign.top + ScaleByZoom(12, dpi->zoom) && |
922 right > st->sign.left && |
934 right > st->sign.left && |
923 left < st->sign.left + st->sign.width_2*4) { |
935 left < st->sign.left + ScaleByZoom(st->sign.width_2, dpi->zoom)) { |
924 AddStation(st, STR_STATION_SIGN_TINY, st->sign.width_2 | 0x8000); |
936 AddStation(st, STR_STATION_SIGN_TINY, st->sign.width_2 | 0x8000); |
925 } |
937 } |
926 } |
938 } |
927 break; |
939 break; |
|
940 |
|
941 case ZOOM_LVL_OUT_16X: |
|
942 break; |
|
943 |
|
944 default: NOT_REACHED(); |
928 } |
945 } |
929 } |
946 } |
930 |
947 |
931 |
948 |
932 static void AddSign(const Sign *si, StringID str, uint16 width) |
949 static void AddSign(const Sign *si, StringID str, uint16 width) |
944 static void ViewportAddSigns(DrawPixelInfo *dpi) |
961 static void ViewportAddSigns(DrawPixelInfo *dpi) |
945 { |
962 { |
946 const Sign *si; |
963 const Sign *si; |
947 int left, top, right, bottom; |
964 int left, top, right, bottom; |
948 |
965 |
949 if (!(_display_opt & DO_SHOW_SIGNS)) |
966 if (!HASBIT(_display_opt, DO_SHOW_SIGNS)) |
950 return; |
967 return; |
951 |
968 |
952 left = dpi->left; |
969 left = dpi->left; |
953 top = dpi->top; |
970 top = dpi->top; |
954 right = left + dpi->width; |
971 right = left + dpi->width; |
955 bottom = top + dpi->height; |
972 bottom = top + dpi->height; |
956 |
973 |
957 switch (dpi->zoom) { |
974 switch (dpi->zoom) { |
958 case 0: |
975 case ZOOM_LVL_NORMAL: |
959 FOR_ALL_SIGNS(si) { |
976 FOR_ALL_SIGNS(si) { |
960 if (bottom > si->sign.top && |
977 if (bottom > si->sign.top && |
961 top < si->sign.top + 12 && |
978 top < si->sign.top + 12 && |
962 right > si->sign.left && |
979 right > si->sign.left && |
963 left < si->sign.left + si->sign.width_1) { |
980 left < si->sign.left + si->sign.width_1) { |
964 AddSign(si, STR_2806, si->sign.width_1); |
981 AddSign(si, STR_2806, si->sign.width_1); |
965 } |
982 } |
966 } |
983 } |
967 break; |
984 break; |
968 |
985 |
969 case 1: |
986 case ZOOM_LVL_OUT_2X: |
970 right += 2; |
987 right += 2; |
971 bottom += 2; |
988 bottom += 2; |
972 FOR_ALL_SIGNS(si) { |
989 FOR_ALL_SIGNS(si) { |
973 if (bottom > si->sign.top && |
990 if (bottom > si->sign.top && |
974 top < si->sign.top + 24 && |
991 top < si->sign.top + 24 && |
977 AddSign(si, STR_2806, si->sign.width_1); |
994 AddSign(si, STR_2806, si->sign.width_1); |
978 } |
995 } |
979 } |
996 } |
980 break; |
997 break; |
981 |
998 |
982 default: NOT_REACHED(); |
999 case ZOOM_LVL_OUT_4X: |
983 case 2: |
1000 case ZOOM_LVL_OUT_8X: |
984 right += 4; |
1001 right += ScaleByZoom(1, dpi->zoom); |
985 bottom += 5; |
1002 bottom += ScaleByZoom(1, dpi->zoom) + 1; |
|
1003 |
986 FOR_ALL_SIGNS(si) { |
1004 FOR_ALL_SIGNS(si) { |
987 if (bottom > si->sign.top && |
1005 if (bottom > si->sign.top && |
988 top < si->sign.top + 24 && |
1006 top < si->sign.top + ScaleByZoom(12, dpi->zoom) && |
989 right > si->sign.left && |
1007 right > si->sign.left && |
990 left < si->sign.left + si->sign.width_2 * 4) { |
1008 left < si->sign.left + ScaleByZoom(si->sign.width_2, dpi->zoom)) { |
991 AddSign(si, STR_2002, si->sign.width_2 | 0x8000); |
1009 AddSign(si, STR_2002, si->sign.width_2 | 0x8000); |
992 } |
1010 } |
993 } |
1011 } |
994 break; |
1012 break; |
|
1013 |
|
1014 case ZOOM_LVL_OUT_16X: |
|
1015 break; |
|
1016 |
|
1017 default: NOT_REACHED(); |
995 } |
1018 } |
996 } |
1019 } |
997 |
1020 |
998 |
1021 |
999 static void AddWaypoint(const Waypoint *wp, StringID str, uint16 width) |
1022 static void AddWaypoint(const Waypoint *wp, StringID str, uint16 width) |
1011 static void ViewportAddWaypoints(DrawPixelInfo *dpi) |
1034 static void ViewportAddWaypoints(DrawPixelInfo *dpi) |
1012 { |
1035 { |
1013 const Waypoint *wp; |
1036 const Waypoint *wp; |
1014 int left, top, right, bottom; |
1037 int left, top, right, bottom; |
1015 |
1038 |
1016 if (!(_display_opt & DO_WAYPOINTS)) |
1039 if (!HASBIT(_display_opt, DO_WAYPOINTS)) |
1017 return; |
1040 return; |
1018 |
1041 |
1019 left = dpi->left; |
1042 left = dpi->left; |
1020 top = dpi->top; |
1043 top = dpi->top; |
1021 right = left + dpi->width; |
1044 right = left + dpi->width; |
1022 bottom = top + dpi->height; |
1045 bottom = top + dpi->height; |
1023 |
1046 |
1024 switch (dpi->zoom) { |
1047 switch (dpi->zoom) { |
1025 case 0: |
1048 case ZOOM_LVL_NORMAL: |
1026 FOR_ALL_WAYPOINTS(wp) { |
1049 FOR_ALL_WAYPOINTS(wp) { |
1027 if (bottom > wp->sign.top && |
1050 if (bottom > wp->sign.top && |
1028 top < wp->sign.top + 12 && |
1051 top < wp->sign.top + 12 && |
1029 right > wp->sign.left && |
1052 right > wp->sign.left && |
1030 left < wp->sign.left + wp->sign.width_1) { |
1053 left < wp->sign.left + wp->sign.width_1) { |
1031 AddWaypoint(wp, STR_WAYPOINT_VIEWPORT, wp->sign.width_1); |
1054 AddWaypoint(wp, STR_WAYPOINT_VIEWPORT, wp->sign.width_1); |
1032 } |
1055 } |
1033 } |
1056 } |
1034 break; |
1057 break; |
1035 |
1058 |
1036 case 1: |
1059 case ZOOM_LVL_OUT_2X: |
1037 right += 2; |
1060 right += 2; |
1038 bottom += 2; |
1061 bottom += 2; |
1039 FOR_ALL_WAYPOINTS(wp) { |
1062 FOR_ALL_WAYPOINTS(wp) { |
1040 if (bottom > wp->sign.top && |
1063 if (bottom > wp->sign.top && |
1041 top < wp->sign.top + 24 && |
1064 top < wp->sign.top + 24 && |
1044 AddWaypoint(wp, STR_WAYPOINT_VIEWPORT, wp->sign.width_1); |
1067 AddWaypoint(wp, STR_WAYPOINT_VIEWPORT, wp->sign.width_1); |
1045 } |
1068 } |
1046 } |
1069 } |
1047 break; |
1070 break; |
1048 |
1071 |
1049 default: NOT_REACHED(); |
1072 case ZOOM_LVL_OUT_4X: |
1050 case 2: |
1073 case ZOOM_LVL_OUT_8X: |
1051 right += 4; |
1074 right += ScaleByZoom(1, dpi->zoom); |
1052 bottom += 5; |
1075 bottom += ScaleByZoom(1, dpi->zoom) + 1; |
|
1076 |
1053 FOR_ALL_WAYPOINTS(wp) { |
1077 FOR_ALL_WAYPOINTS(wp) { |
1054 if (bottom > wp->sign.top && |
1078 if (bottom > wp->sign.top && |
1055 top < wp->sign.top + 24 && |
1079 top < wp->sign.top + ScaleByZoom(12, dpi->zoom) && |
1056 right > wp->sign.left && |
1080 right > wp->sign.left && |
1057 left < wp->sign.left + wp->sign.width_2*4) { |
1081 left < wp->sign.left + ScaleByZoom(wp->sign.width_2, dpi->zoom)) { |
1058 AddWaypoint(wp, STR_WAYPOINT_VIEWPORT_TINY, wp->sign.width_2 | 0x8000); |
1082 AddWaypoint(wp, STR_WAYPOINT_VIEWPORT_TINY, wp->sign.width_2 | 0x8000); |
1059 } |
1083 } |
1060 } |
1084 } |
1061 break; |
1085 break; |
|
1086 |
|
1087 case ZOOM_LVL_OUT_16X: |
|
1088 break; |
|
1089 |
|
1090 default: NOT_REACHED(); |
1062 } |
1091 } |
1063 } |
1092 } |
1064 |
1093 |
1065 void UpdateViewportSignPos(ViewportSign *sign, int left, int top, StringID str) |
1094 void UpdateViewportSignPos(ViewportSign *sign, int left, int top, StringID str) |
1066 { |
1095 { |
1167 } |
1196 } |
1168 |
1197 |
1169 static void ViewportDrawStrings(DrawPixelInfo *dpi, const StringSpriteToDraw *ss) |
1198 static void ViewportDrawStrings(DrawPixelInfo *dpi, const StringSpriteToDraw *ss) |
1170 { |
1199 { |
1171 DrawPixelInfo dp; |
1200 DrawPixelInfo dp; |
1172 byte zoom; |
1201 ZoomLevel zoom; |
1173 |
1202 |
1174 _cur_dpi = &dp; |
1203 _cur_dpi = &dp; |
1175 dp = *dpi; |
1204 dp = *dpi; |
1176 |
1205 |
1177 zoom = dp.zoom; |
1206 zoom = dp.zoom; |
1178 dp.zoom = 0; |
1207 dp.zoom = ZOOM_LVL_NORMAL; |
1179 |
1208 |
1180 dp.left >>= zoom; |
1209 dp.left = UnScaleByZoom(dp.left, zoom); |
1181 dp.top >>= zoom; |
1210 dp.top = UnScaleByZoom(dp.top, zoom); |
1182 dp.width >>= zoom; |
1211 dp.width = UnScaleByZoom(dp.width, zoom); |
1183 dp.height >>= zoom; |
1212 dp.height = UnScaleByZoom(dp.height, zoom); |
1184 |
1213 |
1185 do { |
1214 do { |
1186 uint16 colour; |
1215 uint16 colour; |
1187 |
1216 |
1188 if (ss->width != 0) { |
1217 if (ss->width != 0) { |
1189 int x = (ss->x >> zoom) - 1; |
1218 int x = UnScaleByZoom(ss->x, zoom) - 1; |
1190 int y = (ss->y >> zoom) - 1; |
1219 int y = UnScaleByZoom(ss->y, zoom) - 1; |
1191 int bottom = y + 11; |
1220 int bottom = y + 11; |
1192 int w = ss->width; |
1221 int w = ss->width; |
1193 |
1222 |
1194 if (w & 0x8000) { |
1223 if (w & 0x8000) { |
1195 w &= ~0x8000; |
1224 w &= ~0x8000; |
1198 w -= 3; |
1227 w -= 3; |
1199 } |
1228 } |
1200 |
1229 |
1201 /* Draw the rectangle if 'tranparent station signs' is off, |
1230 /* Draw the rectangle if 'tranparent station signs' is off, |
1202 * or if we are drawing a general text sign (STR_2806) */ |
1231 * or if we are drawing a general text sign (STR_2806) */ |
1203 if (!(_display_opt & DO_TRANS_SIGNS) || ss->string == STR_2806) |
1232 if (!HASBIT(_transparent_opt, TO_SIGNS) || ss->string == STR_2806) { |
1204 DrawFrameRect( |
1233 DrawFrameRect( |
1205 x, y, x + w, bottom, ss->color, |
1234 x, y, x + w, bottom, ss->color, |
1206 (_display_opt & DO_TRANS_BUILDINGS) ? FR_TRANSPARENT : FR_NONE |
1235 HASBIT(_transparent_opt, TO_SIGNS) ? FR_TRANSPARENT : FR_NONE |
1207 ); |
1236 ); |
|
1237 } |
1208 } |
1238 } |
1209 |
1239 |
1210 SetDParam(0, ss->params[0]); |
1240 SetDParam(0, ss->params[0]); |
1211 SetDParam(1, ss->params[1]); |
1241 SetDParam(1, ss->params[1]); |
1212 /* if we didn't draw a rectangle, or if transparant building is on, |
1242 /* if we didn't draw a rectangle, or if transparant building is on, |
1213 * draw the text in the color the rectangle would have */ |
1243 * draw the text in the color the rectangle would have */ |
1214 if (( |
1244 if (HASBIT(_transparent_opt, TO_SIGNS) && ss->string != STR_2806 && ss->width != 0) { |
1215 (_display_opt & DO_TRANS_BUILDINGS) || |
|
1216 (_display_opt & DO_TRANS_SIGNS && ss->string != STR_2806) |
|
1217 ) && ss->width != 0) { |
|
1218 /* Real colors need the IS_PALETTE_COLOR flag |
1245 /* Real colors need the IS_PALETTE_COLOR flag |
1219 * otherwise colors from _string_colormap are assumed. */ |
1246 * otherwise colors from _string_colormap are assumed. */ |
1220 colour = _colour_gradient[ss->color][6] | IS_PALETTE_COLOR; |
1247 colour = _colour_gradient[ss->color][6] | IS_PALETTE_COLOR; |
1221 } else { |
1248 } else { |
1222 colour = 16; |
1249 colour = 16; |
1223 } |
1250 } |
1224 DrawString( |
1251 DrawString( |
1225 ss->x >> zoom, (ss->y >> zoom) - (ss->width & 0x8000 ? 2 : 0), |
1252 UnScaleByZoom(ss->x, zoom), UnScaleByZoom(ss->y, zoom) - (ss->width & 0x8000 ? 2 : 0), |
1226 ss->string, colour |
1253 ss->string, colour |
1227 ); |
1254 ); |
1228 |
1255 |
1229 ss = ss->next; |
1256 ss = ss->next; |
1230 } while (ss != NULL); |
1257 } while (ss != NULL); |
1245 |
1272 |
1246 old_dpi = _cur_dpi; |
1273 old_dpi = _cur_dpi; |
1247 _cur_dpi = &vd.dpi; |
1274 _cur_dpi = &vd.dpi; |
1248 |
1275 |
1249 vd.dpi.zoom = vp->zoom; |
1276 vd.dpi.zoom = vp->zoom; |
1250 mask = (-1) << vp->zoom; |
1277 mask = ScaleByZoom(-1, vp->zoom); |
1251 |
1278 |
1252 vd.combine_sprites = 0; |
1279 vd.combine_sprites = 0; |
1253 |
1280 |
1254 vd.dpi.width = (right - left) & mask; |
1281 vd.dpi.width = (right - left) & mask; |
1255 vd.dpi.height = (bottom - top) & mask; |
1282 vd.dpi.height = (bottom - top) & mask; |
1256 vd.dpi.left = left & mask; |
1283 vd.dpi.left = left & mask; |
1257 vd.dpi.top = top & mask; |
1284 vd.dpi.top = top & mask; |
1258 vd.dpi.pitch = old_dpi->pitch; |
1285 vd.dpi.pitch = old_dpi->pitch; |
1259 |
1286 |
1260 x = ((vd.dpi.left - (vp->virtual_left&mask)) >> vp->zoom) + vp->left; |
1287 x = UnScaleByZoom(vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left; |
1261 y = ((vd.dpi.top - (vp->virtual_top&mask)) >> vp->zoom) + vp->top; |
1288 y = UnScaleByZoom(vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top; |
1262 |
1289 |
1263 vd.dpi.dst_ptr = old_dpi->dst_ptr + x - old_dpi->left + (y - old_dpi->top) * old_dpi->pitch; |
1290 vd.dpi.dst_ptr = old_dpi->dst_ptr + x - old_dpi->left + (y - old_dpi->top) * old_dpi->pitch; |
1264 |
1291 |
1265 vd.parent_list = parent_list; |
1292 vd.parent_list = parent_list; |
1266 vd.eof_parent_list = endof(parent_list); |
1293 vd.eof_parent_list = endof(parent_list); |
1278 ViewportAddTownNames(&vd.dpi); |
1305 ViewportAddTownNames(&vd.dpi); |
1279 ViewportAddStationNames(&vd.dpi); |
1306 ViewportAddStationNames(&vd.dpi); |
1280 ViewportAddSigns(&vd.dpi); |
1307 ViewportAddSigns(&vd.dpi); |
1281 ViewportAddWaypoints(&vd.dpi); |
1308 ViewportAddWaypoints(&vd.dpi); |
1282 |
1309 |
1283 // This assert should never happen (because the length of the parent_list |
1310 /* This assert should never happen (because the length of the parent_list |
1284 // is checked) |
1311 * is checked) */ |
1285 assert(vd.parent_list <= endof(parent_list)); |
1312 assert(vd.parent_list <= endof(parent_list)); |
1286 |
1313 |
1287 if (vd.first_tile != NULL) ViewportDrawTileSprites(vd.first_tile); |
1314 if (vd.first_tile != NULL) ViewportDrawTileSprites(vd.first_tile); |
1288 |
1315 |
1289 /* null terminate parent sprite list */ |
1316 /* null terminate parent sprite list */ |
1295 if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string); |
1322 if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string); |
1296 |
1323 |
1297 _cur_dpi = old_dpi; |
1324 _cur_dpi = old_dpi; |
1298 } |
1325 } |
1299 |
1326 |
1300 // Make sure we don't draw a too big area at a time. |
1327 /** Make sure we don't draw a too big area at a time. |
1301 // If we do, the sprite memory will overflow. |
1328 * If we do, the sprite memory will overflow. */ |
1302 static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom) |
1329 static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom) |
1303 { |
1330 { |
1304 if (((bottom - top) * (right - left) << (2 * vp->zoom)) > 180000) { |
1331 if (ScaleByZoom(bottom - top, vp->zoom) * ScaleByZoom(right - left, vp->zoom) > 180000) { |
1305 if ((bottom - top) > (right - left)) { |
1332 if ((bottom - top) > (right - left)) { |
1306 int t = (top + bottom) >> 1; |
1333 int t = (top + bottom) >> 1; |
1307 ViewportDrawChk(vp, left, top, right, t); |
1334 ViewportDrawChk(vp, left, top, right, t); |
1308 ViewportDrawChk(vp, left, t, right, bottom); |
1335 ViewportDrawChk(vp, left, t, right, bottom); |
1309 } else { |
1336 } else { |
1311 ViewportDrawChk(vp, left, top, t, bottom); |
1338 ViewportDrawChk(vp, left, top, t, bottom); |
1312 ViewportDrawChk(vp, t, top, right, bottom); |
1339 ViewportDrawChk(vp, t, top, right, bottom); |
1313 } |
1340 } |
1314 } else { |
1341 } else { |
1315 ViewportDoDraw(vp, |
1342 ViewportDoDraw(vp, |
1316 ((left - vp->left) << vp->zoom) + vp->virtual_left, |
1343 ScaleByZoom(left - vp->left, vp->zoom) + vp->virtual_left, |
1317 ((top - vp->top) << vp->zoom) + vp->virtual_top, |
1344 ScaleByZoom(top - vp->top, vp->zoom) + vp->virtual_top, |
1318 ((right - vp->left) << vp->zoom) + vp->virtual_left, |
1345 ScaleByZoom(right - vp->left, vp->zoom) + vp->virtual_left, |
1319 ((bottom - vp->top) << vp->zoom) + vp->virtual_top |
1346 ScaleByZoom(bottom - vp->top, vp->zoom) + vp->virtual_top |
1320 ); |
1347 ); |
1321 } |
1348 } |
1322 } |
1349 } |
1323 |
1350 |
1324 static inline void ViewportDraw(const ViewPort *vp, int left, int top, int right, int bottom) |
1351 static inline void ViewportDraw(const ViewPort *vp, int left, int top, int right, int bottom) |
1364 int x; |
1391 int x; |
1365 int y; |
1392 int y; |
1366 int vx; |
1393 int vx; |
1367 int vy; |
1394 int vy; |
1368 |
1395 |
1369 // Center of the viewport is hot spot |
1396 /* Center of the viewport is hot spot */ |
1370 x = WP(w,vp_d).scrollpos_x + vp->virtual_width / 2; |
1397 x = WP(w,vp_d).scrollpos_x + vp->virtual_width / 2; |
1371 y = WP(w,vp_d).scrollpos_y + vp->virtual_height / 2; |
1398 y = WP(w,vp_d).scrollpos_y + vp->virtual_height / 2; |
1372 // Convert viewport coordinates to map coordinates |
1399 |
1373 // Calculation is scaled by 4 to avoid rounding errors |
1400 int dest_x = WP(w,vp_d).dest_scrollpos_x + vp->virtual_width / 2; |
|
1401 int dest_y = WP(w,vp_d).dest_scrollpos_y + vp->virtual_height / 2; |
|
1402 |
|
1403 int delta_x = dest_x - x; |
|
1404 int delta_y = dest_y - y; |
|
1405 |
|
1406 if (delta_x != 0 || delta_y != 0) { |
|
1407 if (_patches.smooth_scroll) { |
|
1408 int max_scroll = ScaleByMapSize1D(512); |
|
1409 /* Not at our desired positon yet... */ |
|
1410 x += clamp(delta_x / 8, -max_scroll, max_scroll); |
|
1411 y += clamp(delta_y / 8, -max_scroll, max_scroll); |
|
1412 } else { |
|
1413 x = dest_x; |
|
1414 y = dest_y; |
|
1415 } |
|
1416 } |
|
1417 |
|
1418 /* Convert viewport coordinates to map coordinates |
|
1419 * Calculation is scaled by 4 to avoid rounding errors */ |
1374 vx = -x + y * 2; |
1420 vx = -x + y * 2; |
1375 vy = x + y * 2; |
1421 vy = x + y * 2; |
1376 // clamp to size of map |
1422 /* clamp to size of map */ |
1377 vx = clamp(vx, 0 * 4, MapMaxX() * TILE_SIZE * 4); |
1423 vx = clamp(vx, 0 * 4, MapMaxX() * TILE_SIZE * 4); |
1378 vy = clamp(vy, 0 * 4, MapMaxY() * TILE_SIZE * 4); |
1424 vy = clamp(vy, 0 * 4, MapMaxY() * TILE_SIZE * 4); |
1379 // Convert map coordinates to viewport coordinates |
1425 /* Convert map coordinates to viewport coordinates */ |
1380 x = (-vx + vy) / 2; |
1426 x = (-vx + vy) / 2; |
1381 y = ( vx + vy) / 4; |
1427 y = ( vx + vy) / 4; |
1382 // Set position |
1428 /* Set position */ |
1383 WP(w, vp_d).scrollpos_x = x - vp->virtual_width / 2; |
1429 WP(w, vp_d).scrollpos_x = x - vp->virtual_width / 2; |
1384 WP(w, vp_d).scrollpos_y = y - vp->virtual_height / 2; |
1430 WP(w, vp_d).scrollpos_y = y - vp->virtual_height / 2; |
1385 |
1431 |
1386 SetViewportPosition(w, WP(w, vp_d).scrollpos_x, WP(w, vp_d).scrollpos_y); |
1432 SetViewportPosition(w, WP(w, vp_d).scrollpos_x, WP(w, vp_d).scrollpos_y); |
1387 } |
1433 } |
1402 top = max(0, top - vp->virtual_top); |
1448 top = max(0, top - vp->virtual_top); |
1403 |
1449 |
1404 if (top >= vp->virtual_height) return; |
1450 if (top >= vp->virtual_height) return; |
1405 |
1451 |
1406 SetDirtyBlocks( |
1452 SetDirtyBlocks( |
1407 (left >> vp->zoom) + vp->left, |
1453 UnScaleByZoom(left, vp->zoom) + vp->left, |
1408 (top >> vp->zoom) + vp->top, |
1454 UnScaleByZoom(top, vp->zoom) + vp->top, |
1409 (right >> vp->zoom) + vp->left, |
1455 UnScaleByZoom(right, vp->zoom) + vp->left, |
1410 (bottom >> vp->zoom) + vp->top |
1456 UnScaleByZoom(bottom, vp->zoom) + vp->top |
1411 ); |
1457 ); |
1412 } |
1458 } |
1413 |
1459 |
1414 void MarkAllViewportsDirty(int left, int top, int right, int bottom) |
1460 void MarkAllViewportsDirty(int left, int top, int right, int bottom) |
1415 { |
1461 { |
1493 |
1539 |
1494 static bool CheckClickOnTown(const ViewPort *vp, int x, int y) |
1540 static bool CheckClickOnTown(const ViewPort *vp, int x, int y) |
1495 { |
1541 { |
1496 const Town *t; |
1542 const Town *t; |
1497 |
1543 |
1498 if (!(_display_opt & DO_SHOW_TOWN_NAMES)) return false; |
1544 if (!HASBIT(_display_opt, DO_SHOW_TOWN_NAMES)) return false; |
1499 |
1545 |
1500 switch (vp->zoom) { |
1546 switch (vp->zoom) { |
1501 case 0: |
1547 case ZOOM_LVL_NORMAL: |
1502 x = x - vp->left + vp->virtual_left; |
1548 x = x - vp->left + vp->virtual_left; |
1503 y = y - vp->top + vp->virtual_top; |
1549 y = y - vp->top + vp->virtual_top; |
1504 FOR_ALL_TOWNS(t) { |
1550 FOR_ALL_TOWNS(t) { |
1505 if (y >= t->sign.top && |
1551 if (y >= t->sign.top && |
1506 y < t->sign.top + 12 && |
1552 y < t->sign.top + 12 && |
1524 return true; |
1570 return true; |
1525 } |
1571 } |
1526 } |
1572 } |
1527 break; |
1573 break; |
1528 |
1574 |
1529 default: |
1575 case ZOOM_LVL_OUT_4X: |
1530 x = (x - vp->left + 3) * 4 + vp->virtual_left; |
1576 case ZOOM_LVL_OUT_8X: |
1531 y = (y - vp->top + 3) * 4 + vp->virtual_top; |
1577 x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left; |
|
1578 y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top; |
|
1579 |
1532 FOR_ALL_TOWNS(t) { |
1580 FOR_ALL_TOWNS(t) { |
1533 if (y >= t->sign.top && |
1581 if (y >= t->sign.top && |
1534 y < t->sign.top + 24 && |
1582 y < t->sign.top + ScaleByZoom(12, vp->zoom) && |
1535 x >= t->sign.left && |
1583 x >= t->sign.left && |
1536 x < t->sign.left + t->sign.width_2 * 4) { |
1584 x < t->sign.left + ScaleByZoom(t->sign.width_2, vp->zoom)) { |
1537 ShowTownViewWindow(t->index); |
1585 ShowTownViewWindow(t->index); |
1538 return true; |
1586 return true; |
1539 } |
1587 } |
1540 } |
1588 } |
1541 break; |
1589 break; |
|
1590 |
|
1591 case ZOOM_LVL_OUT_16X: |
|
1592 break; |
|
1593 |
|
1594 default: NOT_REACHED(); |
1542 } |
1595 } |
1543 |
1596 |
1544 return false; |
1597 return false; |
1545 } |
1598 } |
1546 |
1599 |
1547 |
1600 |
1548 static bool CheckClickOnStation(const ViewPort *vp, int x, int y) |
1601 static bool CheckClickOnStation(const ViewPort *vp, int x, int y) |
1549 { |
1602 { |
1550 const Station *st; |
1603 const Station *st; |
1551 |
1604 |
1552 if (!(_display_opt & DO_SHOW_STATION_NAMES)) return false; |
1605 if (!HASBIT(_display_opt, DO_SHOW_STATION_NAMES)) return false; |
1553 |
1606 |
1554 switch (vp->zoom) { |
1607 switch (vp->zoom) { |
1555 case 0: |
1608 case ZOOM_LVL_NORMAL: |
1556 x = x - vp->left + vp->virtual_left; |
1609 x = x - vp->left + vp->virtual_left; |
1557 y = y - vp->top + vp->virtual_top; |
1610 y = y - vp->top + vp->virtual_top; |
1558 FOR_ALL_STATIONS(st) { |
1611 FOR_ALL_STATIONS(st) { |
1559 if (y >= st->sign.top && |
1612 if (y >= st->sign.top && |
1560 y < st->sign.top + 12 && |
1613 y < st->sign.top + 12 && |
1578 return true; |
1631 return true; |
1579 } |
1632 } |
1580 } |
1633 } |
1581 break; |
1634 break; |
1582 |
1635 |
1583 default: |
1636 case ZOOM_LVL_OUT_4X: |
1584 x = (x - vp->left + 3) * 4 + vp->virtual_left; |
1637 case ZOOM_LVL_OUT_8X: |
1585 y = (y - vp->top + 3) * 4 + vp->virtual_top; |
1638 x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left; |
|
1639 y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top; |
|
1640 |
1586 FOR_ALL_STATIONS(st) { |
1641 FOR_ALL_STATIONS(st) { |
1587 if (y >= st->sign.top && |
1642 if (y >= st->sign.top && |
1588 y < st->sign.top + 24 && |
1643 y < st->sign.top + ScaleByZoom(12, vp->zoom) && |
1589 x >= st->sign.left && |
1644 x >= st->sign.left && |
1590 x < st->sign.left + st->sign.width_2 * 4) { |
1645 x < st->sign.left + ScaleByZoom(st->sign.width_2, vp->zoom)) { |
1591 ShowStationViewWindow(st->index); |
1646 ShowStationViewWindow(st->index); |
1592 return true; |
1647 return true; |
1593 } |
1648 } |
1594 } |
1649 } |
1595 break; |
1650 break; |
|
1651 |
|
1652 case ZOOM_LVL_OUT_16X: |
|
1653 break; |
|
1654 |
|
1655 default: NOT_REACHED(); |
1596 } |
1656 } |
1597 |
1657 |
1598 return false; |
1658 return false; |
1599 } |
1659 } |
1600 |
1660 |
1601 |
1661 |
1602 static bool CheckClickOnSign(const ViewPort *vp, int x, int y) |
1662 static bool CheckClickOnSign(const ViewPort *vp, int x, int y) |
1603 { |
1663 { |
1604 const Sign *si; |
1664 const Sign *si; |
1605 |
1665 |
1606 if (!(_display_opt & DO_SHOW_SIGNS) || _current_player == PLAYER_SPECTATOR) return false; |
1666 if (!HASBIT(_display_opt, DO_SHOW_SIGNS) || _current_player == PLAYER_SPECTATOR) return false; |
1607 |
1667 |
1608 switch (vp->zoom) { |
1668 switch (vp->zoom) { |
1609 case 0: |
1669 case ZOOM_LVL_NORMAL: |
1610 x = x - vp->left + vp->virtual_left; |
1670 x = x - vp->left + vp->virtual_left; |
1611 y = y - vp->top + vp->virtual_top; |
1671 y = y - vp->top + vp->virtual_top; |
1612 FOR_ALL_SIGNS(si) { |
1672 FOR_ALL_SIGNS(si) { |
1613 if (y >= si->sign.top && |
1673 if (y >= si->sign.top && |
1614 y < si->sign.top + 12 && |
1674 y < si->sign.top + 12 && |
1632 return true; |
1692 return true; |
1633 } |
1693 } |
1634 } |
1694 } |
1635 break; |
1695 break; |
1636 |
1696 |
1637 default: |
1697 case ZOOM_LVL_OUT_4X: |
1638 x = (x - vp->left + 3) * 4 + vp->virtual_left; |
1698 case ZOOM_LVL_OUT_8X: |
1639 y = (y - vp->top + 3) * 4 + vp->virtual_top; |
1699 x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left; |
|
1700 y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top; |
|
1701 |
1640 FOR_ALL_SIGNS(si) { |
1702 FOR_ALL_SIGNS(si) { |
1641 if (y >= si->sign.top && |
1703 if (y >= si->sign.top && |
1642 y < si->sign.top + 24 && |
1704 y < si->sign.top + ScaleByZoom(12, vp->zoom) && |
1643 x >= si->sign.left && |
1705 x >= si->sign.left && |
1644 x < si->sign.left + si->sign.width_2 * 4) { |
1706 x < si->sign.left + ScaleByZoom(si->sign.width_2, vp->zoom)) { |
1645 ShowRenameSignWindow(si); |
1707 ShowRenameSignWindow(si); |
1646 return true; |
1708 return true; |
1647 } |
1709 } |
1648 } |
1710 } |
1649 break; |
1711 break; |
|
1712 |
|
1713 case ZOOM_LVL_OUT_16X: |
|
1714 break; |
|
1715 |
|
1716 default: NOT_REACHED(); |
1650 } |
1717 } |
1651 |
1718 |
1652 return false; |
1719 return false; |
1653 } |
1720 } |
1654 |
1721 |
1655 |
1722 |
1656 static bool CheckClickOnWaypoint(const ViewPort *vp, int x, int y) |
1723 static bool CheckClickOnWaypoint(const ViewPort *vp, int x, int y) |
1657 { |
1724 { |
1658 const Waypoint *wp; |
1725 const Waypoint *wp; |
1659 |
1726 |
1660 if (!(_display_opt & DO_WAYPOINTS)) return false; |
1727 if (!HASBIT(_display_opt, DO_WAYPOINTS)) return false; |
1661 |
1728 |
1662 switch (vp->zoom) { |
1729 switch (vp->zoom) { |
1663 case 0: |
1730 case ZOOM_LVL_NORMAL: |
1664 x = x - vp->left + vp->virtual_left; |
1731 x = x - vp->left + vp->virtual_left; |
1665 y = y - vp->top + vp->virtual_top; |
1732 y = y - vp->top + vp->virtual_top; |
1666 FOR_ALL_WAYPOINTS(wp) { |
1733 FOR_ALL_WAYPOINTS(wp) { |
1667 if (y >= wp->sign.top && |
1734 if (y >= wp->sign.top && |
1668 y < wp->sign.top + 12 && |
1735 y < wp->sign.top + 12 && |
1686 return true; |
1753 return true; |
1687 } |
1754 } |
1688 } |
1755 } |
1689 break; |
1756 break; |
1690 |
1757 |
1691 default: |
1758 case ZOOM_LVL_OUT_4X: |
1692 x = (x - vp->left + 3) * 4 + vp->virtual_left; |
1759 case ZOOM_LVL_OUT_8X: |
1693 y = (y - vp->top + 3) * 4 + vp->virtual_top; |
1760 x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left; |
|
1761 y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top; |
|
1762 |
1694 FOR_ALL_WAYPOINTS(wp) { |
1763 FOR_ALL_WAYPOINTS(wp) { |
1695 if (y >= wp->sign.top && |
1764 if (y >= wp->sign.top && |
1696 y < wp->sign.top + 24 && |
1765 y < wp->sign.top + ScaleByZoom(12, vp->zoom) && |
1697 x >= wp->sign.left && |
1766 x >= wp->sign.left && |
1698 x < wp->sign.left + wp->sign.width_2 * 4) { |
1767 x < wp->sign.left + ScaleByZoom(wp->sign.width_2, vp->zoom)) { |
1699 ShowRenameWaypointWindow(wp); |
1768 ShowRenameWaypointWindow(wp); |
1700 return true; |
1769 return true; |
1701 } |
1770 } |
1702 } |
1771 } |
1703 break; |
1772 break; |
|
1773 |
|
1774 case ZOOM_LVL_OUT_16X: |
|
1775 break; |
|
1776 |
|
1777 default: NOT_REACHED(); |
1704 } |
1778 } |
1705 |
1779 |
1706 return false; |
1780 return false; |
1707 } |
1781 } |
1708 |
1782 |
1794 } |
1868 } |
1795 } |
1869 } |
1796 |
1870 |
1797 |
1871 |
1798 /* scrolls the viewport in a window to a given location */ |
1872 /* scrolls the viewport in a window to a given location */ |
1799 bool ScrollWindowTo(int x , int y, Window *w) |
1873 bool ScrollWindowTo(int x , int y, Window *w, bool instant) |
1800 { |
1874 { |
1801 Point pt; |
1875 Point pt; |
1802 |
1876 |
1803 pt = MapXYZToViewport(w->viewport, x, y, GetSlopeZ(x, y)); |
1877 pt = MapXYZToViewport(w->viewport, x, y, GetSlopeZ(x, y)); |
1804 WP(w, vp_d).follow_vehicle = INVALID_VEHICLE; |
1878 WP(w, vp_d).follow_vehicle = INVALID_VEHICLE; |
1805 |
1879 |
1806 if (WP(w, vp_d).scrollpos_x == pt.x && WP(w, vp_d).scrollpos_y == pt.y) |
1880 if (WP(w, vp_d).dest_scrollpos_x == pt.x && WP(w, vp_d).dest_scrollpos_y == pt.y) |
1807 return false; |
1881 return false; |
1808 |
1882 |
1809 WP(w, vp_d).scrollpos_x = pt.x; |
1883 if (instant) { |
1810 WP(w, vp_d).scrollpos_y = pt.y; |
1884 WP(w, vp_d).scrollpos_x = pt.x; |
|
1885 WP(w, vp_d).scrollpos_y = pt.y; |
|
1886 } |
|
1887 |
|
1888 WP(w, vp_d).dest_scrollpos_x = pt.x; |
|
1889 WP(w, vp_d).dest_scrollpos_y = pt.y; |
1811 return true; |
1890 return true; |
1812 } |
1891 } |
1813 |
1892 |
1814 |
1893 |
1815 bool ScrollMainWindowTo(int x, int y) |
1894 bool ScrollMainWindowTo(int x, int y, bool instant) |
1816 { |
1895 { |
1817 Window *w; |
1896 Window *w; |
1818 bool res = ScrollWindowTo(x, y, FindWindowById(WC_MAIN_WINDOW, 0)); |
1897 bool res = ScrollWindowTo(x, y, FindWindowById(WC_MAIN_WINDOW, 0), instant); |
1819 |
1898 |
1820 /* If a user scrolls to a tile (via what way what so ever) and already is on |
1899 /* If a user scrolls to a tile (via what way what so ever) and already is on |
1821 * that tile (e.g.: pressed twice), move the smallmap to that location, |
1900 * that tile (e.g.: pressed twice), move the smallmap to that location, |
1822 * so you directly see where you are on the smallmap. */ |
1901 * so you directly see where you are on the smallmap. */ |
1823 |
1902 |
1864 _thd.offs.y = oy * TILE_SIZE; |
1943 _thd.offs.y = oy * TILE_SIZE; |
1865 _thd.new_outersize.x = sx * TILE_SIZE; |
1944 _thd.new_outersize.x = sx * TILE_SIZE; |
1866 _thd.new_outersize.y = sy * TILE_SIZE; |
1945 _thd.new_outersize.y = sy * TILE_SIZE; |
1867 } |
1946 } |
1868 |
1947 |
1869 /* returns the best autorail highlight type from map coordinates */ |
1948 /** returns the best autorail highlight type from map coordinates */ |
1870 static byte GetAutorailHT(int x, int y) |
1949 static byte GetAutorailHT(int x, int y) |
1871 { |
1950 { |
1872 return HT_RAIL | _AutorailPiece[x & 0xF][y & 0xF]; |
1951 return HT_RAIL | _AutorailPiece[x & 0xF][y & 0xF]; |
1873 } |
1952 } |
1874 |
1953 |
1875 // called regular to update tile highlighting in all cases |
1954 /** called regular to update tile highlighting in all cases */ |
1876 void UpdateTileSelection() |
1955 void UpdateTileSelection() |
1877 { |
1956 { |
1878 int x1; |
1957 int x1; |
1879 int y1; |
1958 int y1; |
1880 |
1959 |
1917 _thd.new_pos.x = x1 & ~0xF; |
1996 _thd.new_pos.x = x1 & ~0xF; |
1918 _thd.new_pos.y = y1 & ~0xF; |
1997 _thd.new_pos.y = y1 & ~0xF; |
1919 } |
1998 } |
1920 } |
1999 } |
1921 |
2000 |
1922 // redraw selection |
2001 /* redraw selection */ |
1923 if (_thd.drawstyle != _thd.new_drawstyle || |
2002 if (_thd.drawstyle != _thd.new_drawstyle || |
1924 _thd.pos.x != _thd.new_pos.x || _thd.pos.y != _thd.new_pos.y || |
2003 _thd.pos.x != _thd.new_pos.x || _thd.pos.y != _thd.new_pos.y || |
1925 _thd.size.x != _thd.new_size.x || _thd.size.y != _thd.new_size.y || |
2004 _thd.size.x != _thd.new_size.x || _thd.size.y != _thd.new_size.y || |
1926 _thd.outersize.x != _thd.new_outersize.x || |
2005 _thd.outersize.x != _thd.new_outersize.x || |
1927 _thd.outersize.y != _thd.new_outersize.y) { |
2006 _thd.outersize.y != _thd.new_outersize.y) { |
1928 // clear the old selection? |
2007 /* clear the old selection? */ |
1929 if (_thd.drawstyle) SetSelectionTilesDirty(); |
2008 if (_thd.drawstyle) SetSelectionTilesDirty(); |
1930 |
2009 |
1931 _thd.drawstyle = _thd.new_drawstyle; |
2010 _thd.drawstyle = _thd.new_drawstyle; |
1932 _thd.pos = _thd.new_pos; |
2011 _thd.pos = _thd.new_pos; |
1933 _thd.size = _thd.new_size; |
2012 _thd.size = _thd.new_size; |
1934 _thd.outersize = _thd.new_outersize; |
2013 _thd.outersize = _thd.new_outersize; |
1935 _thd.dirty = 0xff; |
2014 _thd.dirty = 0xff; |
1936 |
2015 |
1937 // draw the new selection? |
2016 /* draw the new selection? */ |
1938 if (_thd.new_drawstyle) SetSelectionTilesDirty(); |
2017 if (_thd.new_drawstyle) SetSelectionTilesDirty(); |
1939 } |
2018 } |
1940 } |
2019 } |
1941 |
2020 |
1942 // highlighting tiles while only going over them with the mouse |
2021 /** highlighting tiles while only going over them with the mouse */ |
1943 void VpStartPlaceSizing(TileIndex tile, int user) |
2022 void VpStartPlaceSizing(TileIndex tile, byte method, byte process) |
1944 { |
2023 { |
1945 _thd.userdata = user; |
2024 _thd.select_method = method; |
|
2025 _thd.select_proc = process; |
1946 _thd.selend.x = TileX(tile) * TILE_SIZE; |
2026 _thd.selend.x = TileX(tile) * TILE_SIZE; |
1947 _thd.selstart.x = TileX(tile) * TILE_SIZE; |
2027 _thd.selstart.x = TileX(tile) * TILE_SIZE; |
1948 _thd.selend.y = TileY(tile) * TILE_SIZE; |
2028 _thd.selend.y = TileY(tile) * TILE_SIZE; |
1949 _thd.selstart.y = TileY(tile) * TILE_SIZE; |
2029 _thd.selstart.y = TileY(tile) * TILE_SIZE; |
1950 if (_thd.place_mode == VHM_RECT) { |
2030 if (_thd.place_mode == VHM_RECT) { |
2029 * in the case of a rect (HT_RECT, HT_POINT): DIR_S, DIR_E |
2109 * in the case of a rect (HT_RECT, HT_POINT): DIR_S, DIR_E |
2030 * For example dragging a rectangle area from south to north should be swapped to |
2110 * For example dragging a rectangle area from south to north should be swapped to |
2031 * north-south (DIR_S) to obtain the same results with less code. This is what |
2111 * north-south (DIR_S) to obtain the same results with less code. This is what |
2032 * the return value signifies. |
2112 * the return value signifies. |
2033 * @param style HighLightStyle dragging style |
2113 * @param style HighLightStyle dragging style |
2034 * @param start_tile, end_tile start and end tile of drag |
2114 * @param start_tile start tile of drag |
2035 * @param boolean value which when true means start/end should be swapped */ |
2115 * @param end_tile end tile of drag |
|
2116 * @return boolean value which when true means start/end should be swapped */ |
2036 static bool SwapDirection(HighLightStyle style, TileIndex start_tile, TileIndex end_tile) |
2117 static bool SwapDirection(HighLightStyle style, TileIndex start_tile, TileIndex end_tile) |
2037 { |
2118 { |
2038 uint start_x = TileX(start_tile); |
2119 uint start_x = TileX(start_tile); |
2039 uint start_y = TileY(start_tile); |
2120 uint start_y = TileY(start_tile); |
2040 uint end_x = TileX(end_tile); |
2121 uint end_x = TileX(end_tile); |
2055 /** Calculates height difference between one tile and another |
2136 /** Calculates height difference between one tile and another |
2056 * Multiplies the result to suit the standard given by minimap - 50 meters high |
2137 * Multiplies the result to suit the standard given by minimap - 50 meters high |
2057 * To correctly get the height difference we need the direction we are dragging |
2138 * To correctly get the height difference we need the direction we are dragging |
2058 * in, as well as with what kind of tool we are dragging. For example a horizontal |
2139 * in, as well as with what kind of tool we are dragging. For example a horizontal |
2059 * autorail tool that starts in bottom and ends at the top of a tile will need the |
2140 * autorail tool that starts in bottom and ends at the top of a tile will need the |
2060 * maximum of SW,S and SE,N corners respectively. This is handled by the lookup table below |
2141 * maximum of SW, S and SE, N corners respectively. This is handled by the lookup table below |
2061 * See _tileoffs_by_dir in map.c for the direction enums if you can't figure out |
2142 * See _tileoffs_by_dir in map.c for the direction enums if you can't figure out |
2062 * the values yourself. |
2143 * the values yourself. |
2063 * @param style HightlightStyle of drag. This includes direction and style (autorail, rect, etc.) |
2144 * @param style HightlightStyle of drag. This includes direction and style (autorail, rect, etc.) |
2064 * @param distance amount of tiles dragged, important for horizontal/vertical drags |
2145 * @param distance amount of tiles dragged, important for horizontal/vertical drags |
2065 * ignored for others |
2146 * ignored for others |
2389 |
2470 |
2390 _thd.selend.x = x; |
2471 _thd.selend.x = x; |
2391 _thd.selend.y = y; |
2472 _thd.selend.y = y; |
2392 } |
2473 } |
2393 |
2474 |
2394 // while dragging |
2475 /** while dragging */ |
2395 bool VpHandlePlaceSizingDrag() |
2476 bool VpHandlePlaceSizingDrag() |
2396 { |
2477 { |
2397 Window *w; |
2478 Window *w; |
2398 WindowEvent e; |
2479 WindowEvent e; |
2399 |
2480 |
2400 if (_special_mouse_mode != WSM_SIZING) return true; |
2481 if (_special_mouse_mode != WSM_SIZING) return true; |
2401 |
2482 |
2402 e.we.place.userdata = _thd.userdata; |
2483 e.we.place.select_method = _thd.select_method; |
2403 |
2484 e.we.place.select_proc = _thd.select_proc; |
2404 // stop drag mode if the window has been closed |
2485 |
2405 w = FindWindowById(_thd.window_class,_thd.window_number); |
2486 /* stop drag mode if the window has been closed */ |
|
2487 w = FindWindowById(_thd.window_class, _thd.window_number); |
2406 if (w == NULL) { |
2488 if (w == NULL) { |
2407 ResetObjectToPlace(); |
2489 ResetObjectToPlace(); |
2408 return false; |
2490 return false; |
2409 } |
2491 } |
2410 |
2492 |
2411 // while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() ) |
2493 /* while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() ) */ |
2412 if (_left_button_down) { |
2494 if (_left_button_down) { |
2413 e.event = WE_PLACE_DRAG; |
2495 e.event = WE_PLACE_DRAG; |
2414 e.we.place.pt = GetTileBelowCursor(); |
2496 e.we.place.pt = GetTileBelowCursor(); |
2415 w->wndproc(w, &e); |
2497 w->wndproc(w, &e); |
2416 return false; |
2498 return false; |
2417 } |
2499 } |
2418 |
2500 |
2419 // mouse button released.. |
2501 /* mouse button released.. |
2420 // keep the selected tool, but reset it to the original mode. |
2502 * keep the selected tool, but reset it to the original mode. */ |
2421 _special_mouse_mode = WSM_NONE; |
2503 _special_mouse_mode = WSM_NONE; |
2422 if (_thd.next_drawstyle == HT_RECT) { |
2504 if (_thd.next_drawstyle == HT_RECT) { |
2423 _thd.place_mode = VHM_RECT; |
2505 _thd.place_mode = VHM_RECT; |
2424 } else if ((e.we.place.userdata & 0xF) == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik |
2506 } else if (e.we.place.select_method == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik |
2425 _thd.place_mode = VHM_RECT; |
2507 _thd.place_mode = VHM_RECT; |
2426 } else if (_thd.next_drawstyle & HT_LINE) { |
2508 } else if (_thd.next_drawstyle & HT_LINE) { |
2427 _thd.place_mode = VHM_RAIL; |
2509 _thd.place_mode = VHM_RAIL; |
2428 } else if (_thd.next_drawstyle & HT_RAIL) { |
2510 } else if (_thd.next_drawstyle & HT_RAIL) { |
2429 _thd.place_mode = VHM_RAIL; |
2511 _thd.place_mode = VHM_RAIL; |
2430 } else { |
2512 } else { |
2431 _thd.place_mode = VHM_POINT; |
2513 _thd.place_mode = VHM_POINT; |
2432 } |
2514 } |
2433 SetTileSelectSize(1, 1); |
2515 SetTileSelectSize(1, 1); |
2434 |
2516 |
2435 // and call the mouseup event. |
2517 /* and call the mouseup event. */ |
2436 e.event = WE_PLACE_MOUSEUP; |
2518 e.event = WE_PLACE_MOUSEUP; |
2437 e.we.place.pt = _thd.selend; |
2519 e.we.place.pt = _thd.selend; |
2438 e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y); |
2520 e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y); |
2439 e.we.place.starttile = TileVirtXY(_thd.selstart.x, _thd.selstart.y); |
2521 e.we.place.starttile = TileVirtXY(_thd.selstart.x, _thd.selstart.y); |
2440 w->wndproc(w, &e); |
2522 w->wndproc(w, &e); |
2451 |
2533 |
2452 void SetObjectToPlace(CursorID icon, SpriteID pal, byte mode, WindowClass window_class, WindowNumber window_num) |
2534 void SetObjectToPlace(CursorID icon, SpriteID pal, byte mode, WindowClass window_class, WindowNumber window_num) |
2453 { |
2535 { |
2454 Window *w; |
2536 Window *w; |
2455 |
2537 |
2456 // undo clicking on button |
2538 /* undo clicking on button */ |
2457 if (_thd.place_mode != 0) { |
2539 if (_thd.place_mode != 0) { |
2458 _thd.place_mode = 0; |
2540 _thd.place_mode = 0; |
2459 w = FindWindowById(_thd.window_class, _thd.window_number); |
2541 w = FindWindowById(_thd.window_class, _thd.window_number); |
2460 if (w != NULL) CallWindowEventNP(w, WE_ABORT_PLACE_OBJ); |
2542 if (w != NULL) CallWindowEventNP(w, WE_ABORT_PLACE_OBJ); |
2461 } |
2543 } |