1#include "layer_group.h"
2
3#include <base/math.h>
4#include <game/editor/editor.h>
5
6CLayerGroup::CLayerGroup()
7{
8 m_vpLayers.clear();
9 m_aName[0] = 0;
10 m_Visible = true;
11 m_Collapse = false;
12 m_GameGroup = false;
13 m_OffsetX = 0;
14 m_OffsetY = 0;
15 m_ParallaxX = 100;
16 m_ParallaxY = 100;
17
18 m_UseClipping = 0;
19 m_ClipX = 0;
20 m_ClipY = 0;
21 m_ClipW = 0;
22 m_ClipH = 0;
23}
24
25CLayerGroup::~CLayerGroup()
26{
27 m_vpLayers.clear();
28}
29
30void CLayerGroup::Convert(CUIRect *pRect) const
31{
32 pRect->x += m_OffsetX;
33 pRect->y += m_OffsetY;
34}
35
36void CLayerGroup::Mapping(float *pPoints) const
37{
38 float NormalParallaxZoom = clamp(val: (double)(maximum(a: m_ParallaxX, b: m_ParallaxY)), lo: 0., hi: 100.);
39 float ParallaxZoom = m_pMap->m_pEditor->m_PreviewZoom ? NormalParallaxZoom : 100.0f;
40
41 m_pMap->m_pEditor->RenderTools()->MapScreenToWorld(
42 CenterX: m_pMap->m_pEditor->MapView()->GetWorldOffset().x, CenterY: m_pMap->m_pEditor->MapView()->GetWorldOffset().y,
43 ParallaxX: m_ParallaxX, ParallaxY: m_ParallaxY, ParallaxZoom, OffsetX: m_OffsetX, OffsetY: m_OffsetY,
44 Aspect: m_pMap->m_pEditor->Graphics()->ScreenAspect(), Zoom: m_pMap->m_pEditor->MapView()->GetWorldZoom(), pPoints);
45
46 pPoints[0] += m_pMap->m_pEditor->MapView()->GetEditorOffset().x;
47 pPoints[1] += m_pMap->m_pEditor->MapView()->GetEditorOffset().y;
48 pPoints[2] += m_pMap->m_pEditor->MapView()->GetEditorOffset().x;
49 pPoints[3] += m_pMap->m_pEditor->MapView()->GetEditorOffset().y;
50}
51
52void CLayerGroup::MapScreen() const
53{
54 float aPoints[4];
55 Mapping(pPoints: aPoints);
56 m_pMap->m_pEditor->Graphics()->MapScreen(TopLeftX: aPoints[0], TopLeftY: aPoints[1], BottomRightX: aPoints[2], BottomRightY: aPoints[3]);
57}
58
59void CLayerGroup::Render()
60{
61 MapScreen();
62 IGraphics *pGraphics = m_pMap->m_pEditor->Graphics();
63
64 if(m_UseClipping)
65 {
66 float aPoints[4];
67 m_pMap->m_pGameGroup->Mapping(pPoints: aPoints);
68 float x0 = (m_ClipX - aPoints[0]) / (aPoints[2] - aPoints[0]);
69 float y0 = (m_ClipY - aPoints[1]) / (aPoints[3] - aPoints[1]);
70 float x1 = ((m_ClipX + m_ClipW) - aPoints[0]) / (aPoints[2] - aPoints[0]);
71 float y1 = ((m_ClipY + m_ClipH) - aPoints[1]) / (aPoints[3] - aPoints[1]);
72
73 pGraphics->ClipEnable(x: (int)(x0 * pGraphics->ScreenWidth()), y: (int)(y0 * pGraphics->ScreenHeight()),
74 w: (int)((x1 - x0) * pGraphics->ScreenWidth()), h: (int)((y1 - y0) * pGraphics->ScreenHeight()));
75 }
76
77 for(auto &pLayer : m_vpLayers)
78 {
79 if(pLayer->m_Visible)
80 {
81 if(pLayer->m_Type == LAYERTYPE_TILES)
82 {
83 std::shared_ptr<CLayerTiles> pTiles = std::static_pointer_cast<CLayerTiles>(r: pLayer);
84 if(pTiles->m_Game || pTiles->m_Front || pTiles->m_Tele || pTiles->m_Speedup || pTiles->m_Tune || pTiles->m_Switch)
85 continue;
86 }
87 if(m_pMap->m_pEditor->m_ShowDetail || !(pLayer->m_Flags & LAYERFLAG_DETAIL))
88 pLayer->Render();
89 }
90 }
91
92 for(auto &pLayer : m_vpLayers)
93 {
94 if(pLayer->m_Visible && pLayer->m_Type == LAYERTYPE_TILES && pLayer != m_pMap->m_pGameLayer && pLayer != m_pMap->m_pFrontLayer && pLayer != m_pMap->m_pTeleLayer && pLayer != m_pMap->m_pSpeedupLayer && pLayer != m_pMap->m_pSwitchLayer && pLayer != m_pMap->m_pTuneLayer)
95 {
96 std::shared_ptr<CLayerTiles> pTiles = std::static_pointer_cast<CLayerTiles>(r: pLayer);
97 if(pTiles->m_Game || pTiles->m_Front || pTiles->m_Tele || pTiles->m_Speedup || pTiles->m_Tune || pTiles->m_Switch)
98 {
99 pLayer->Render();
100 }
101 }
102 }
103
104 if(m_UseClipping)
105 pGraphics->ClipDisable();
106}
107
108void CLayerGroup::AddLayer(const std::shared_ptr<CLayer> &pLayer)
109{
110 m_pMap->OnModify();
111 m_vpLayers.push_back(x: pLayer);
112}
113
114void CLayerGroup::DeleteLayer(int Index)
115{
116 if(Index < 0 || Index >= (int)m_vpLayers.size())
117 return;
118 m_vpLayers.erase(position: m_vpLayers.begin() + Index);
119 m_pMap->OnModify();
120}
121
122void CLayerGroup::DuplicateLayer(int Index)
123{
124 if(Index < 0 || Index >= (int)m_vpLayers.size())
125 return;
126
127 std::shared_ptr<CLayer> pDup = m_vpLayers[Index]->Duplicate();
128 m_vpLayers.insert(position: m_vpLayers.begin() + Index + 1, x: pDup);
129
130 m_pMap->OnModify();
131}
132
133void CLayerGroup::GetSize(float *pWidth, float *pHeight) const
134{
135 *pWidth = 0;
136 *pHeight = 0;
137 for(const auto &pLayer : m_vpLayers)
138 {
139 float lw, lh;
140 pLayer->GetSize(pWidth: &lw, pHeight: &lh);
141 *pWidth = maximum(a: *pWidth, b: lw);
142 *pHeight = maximum(a: *pHeight, b: lh);
143 }
144}
145
146int CLayerGroup::SwapLayers(int Index0, int Index1)
147{
148 if(Index0 < 0 || Index0 >= (int)m_vpLayers.size())
149 return Index0;
150 if(Index1 < 0 || Index1 >= (int)m_vpLayers.size())
151 return Index0;
152 if(Index0 == Index1)
153 return Index0;
154 m_pMap->OnModify();
155 std::swap(a&: m_vpLayers[Index0], b&: m_vpLayers[Index1]);
156 return Index1;
157}
158