1 /*****************************************************************************
2  * Copyright (c) 2014-2020 OpenRCT2 developers
3  *
4  * For a complete list of all authors, please refer to contributors.md
5  * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
6  *
7  * OpenRCT2 is licensed under the GNU General Public License version 3.
8  *****************************************************************************/
9 
10 #include "../../Game.h"
11 #include "../../config/Config.h"
12 #include "../../interface/Viewport.h"
13 #include "../../localisation/Localisation.h"
14 #include "../../ride/TrackDesign.h"
15 #include "../../sprites.h"
16 #include "../../world/Banner.h"
17 #include "../../world/Scenery.h"
18 #include "../../world/TileInspector.h"
19 #include "../Paint.h"
20 #include "Paint.TileElement.h"
21 
22 /** rct2: 0x0098D884 */
23 // BannerBoundBoxes[rotation][0] is for the pole in the back
24 // BannerBoundBoxes[rotation][1] is for the pole and the banner in the front
25 constexpr CoordsXY BannerBoundBoxes[][2] = {
26     { { 1, 2 }, { 1, 29 } },
27     { { 2, 32 }, { 29, 32 } },
28     { { 32, 2 }, { 32, 29 } },
29     { { 2, 1 }, { 29, 1 } },
30 };
31 
32 /**
33  *
34  *  rct2: 0x006B9CC4
35  */
PaintBanner(paint_session * session,uint8_t direction,int32_t height,const BannerElement & bannerElement)36 void PaintBanner(paint_session* session, uint8_t direction, int32_t height, const BannerElement& bannerElement)
37 {
38     rct_drawpixelinfo* dpi = &session->DPI;
39 
40     session->InteractionType = ViewportInteractionItem::Banner;
41 
42     if (dpi->zoom_level > 1 || gTrackDesignSaveMode || (session->ViewFlags & VIEWPORT_FLAG_HIGHLIGHT_PATH_ISSUES))
43         return;
44 
45     height -= 16;
46 
47     auto banner = bannerElement.GetBanner();
48     if (banner == nullptr)
49     {
50         return;
51     }
52 
53     auto* bannerEntry = get_banner_entry(banner->type);
54     if (bannerEntry == nullptr)
55     {
56         return;
57     }
58 
59     direction += bannerElement.GetPosition();
60     direction &= 3;
61 
62     CoordsXYZ boundBoxOffset = CoordsXYZ(BannerBoundBoxes[direction][0], height + 2);
63 
64     uint32_t base_id = (direction << 1) + bannerEntry->image;
65     uint32_t image_id = base_id;
66 
67     if (bannerElement.IsGhost()) // if being placed
68     {
69         session->InteractionType = ViewportInteractionItem::None;
70         image_id |= CONSTRUCTION_MARKER;
71     }
72     else if (OpenRCT2::TileInspector::IsElementSelected(reinterpret_cast<const TileElement*>(&bannerElement)))
73     {
74         image_id |= CONSTRUCTION_MARKER;
75     }
76     else
77     {
78         image_id |= (banner->colour << 19) | IMAGE_TYPE_REMAP;
79     }
80 
81     PaintAddImageAsParent(session, image_id, { 0, 0, height }, { 1, 1, 0x15 }, boundBoxOffset);
82     boundBoxOffset.x = BannerBoundBoxes[direction][1].x;
83     boundBoxOffset.y = BannerBoundBoxes[direction][1].y;
84 
85     image_id++;
86     PaintAddImageAsParent(session, image_id, { 0, 0, height }, { 1, 1, 0x15 }, boundBoxOffset);
87 
88     // Opposite direction
89     direction = direction_reverse(direction);
90     direction--;
91     // If text not showing / ghost
92     if (direction >= 2 || (bannerElement.IsGhost()))
93         return;
94 
95     uint16_t scrollingMode = bannerEntry->scrolling_mode;
96     if (scrollingMode >= MAX_SCROLLING_TEXT_MODES)
97     {
98         return;
99     }
100 
101     scrollingMode += direction;
102 
103     auto ft = Formatter();
104     banner->FormatTextTo(ft, /*addColour*/ true);
105 
106     if (gConfigGeneral.upper_case_banners)
107     {
108         format_string_to_upper(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_BANNER_TEXT_FORMAT, ft.Data());
109     }
110     else
111     {
112         format_string(gCommonStringFormatBuffer, sizeof(gCommonStringFormatBuffer), STR_BANNER_TEXT_FORMAT, ft.Data());
113     }
114 
115     uint16_t string_width = gfx_get_string_width(gCommonStringFormatBuffer, FontSpriteBase::TINY);
116     uint16_t scroll = (gCurrentTicks / 2) % string_width;
117     auto scrollIndex = scrolling_text_setup(session, STR_BANNER_TEXT_FORMAT, ft, scroll, scrollingMode, COLOUR_BLACK);
118     PaintAddImageAsChild(
119         session, scrollIndex, 0, 0, 1, 1, 0x15, height + 22, boundBoxOffset.x, boundBoxOffset.y, boundBoxOffset.z);
120 }
121