1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3#ifndef GAME_CLIENT_COMPONENTS_MAPLAYERS_H
4#define GAME_CLIENT_COMPONENTS_MAPLAYERS_H
5#include <game/client/component.h>
6
7#include <cstdint>
8#include <vector>
9
10#define INDEX_BUFFER_GROUP_WIDTH 12
11#define INDEX_BUFFER_GROUP_HEIGHT 9
12#define INDEX_BORDER_BUFFER_GROUP_SIZE 20
13
14typedef char *offset_ptr_size;
15typedef uintptr_t offset_ptr;
16typedef unsigned int offset_ptr32;
17
18class CCamera;
19class CLayers;
20class CMapImages;
21class ColorRGBA;
22struct CMapItemGroup;
23struct CMapItemLayerTilemap;
24struct CMapItemLayerQuads;
25
26class CMapLayers : public CComponent
27{
28 friend class CBackground;
29 friend class CMenuBackground;
30
31 CLayers *m_pLayers;
32 CMapImages *m_pImages;
33 int m_Type;
34 int m_CurrentLocalTick;
35 int m_LastLocalTick;
36 bool m_EnvelopeUpdate;
37
38 bool m_OnlineOnly;
39
40 struct STileLayerVisuals
41 {
42 STileLayerVisuals() :
43 m_pTilesOfLayer(nullptr)
44 {
45 m_Width = 0;
46 m_Height = 0;
47 m_BufferContainerIndex = -1;
48 m_IsTextured = false;
49 }
50
51 bool Init(unsigned int Width, unsigned int Height);
52
53 ~STileLayerVisuals();
54
55 struct STileVisual
56 {
57 STileVisual() :
58 m_IndexBufferByteOffset(0) {}
59
60 private:
61 offset_ptr32 m_IndexBufferByteOffset;
62
63 public:
64 bool DoDraw()
65 {
66 return (m_IndexBufferByteOffset & 0x10000000) != 0;
67 }
68
69 void Draw(bool SetDraw)
70 {
71 m_IndexBufferByteOffset = (SetDraw ? 0x10000000 : (offset_ptr32)0) | (m_IndexBufferByteOffset & 0xEFFFFFFF);
72 }
73
74 offset_ptr IndexBufferByteOffset()
75 {
76 return ((offset_ptr)(m_IndexBufferByteOffset & 0xEFFFFFFF) * 6 * sizeof(uint32_t));
77 }
78
79 void SetIndexBufferByteOffset(offset_ptr32 IndexBufferByteOff)
80 {
81 m_IndexBufferByteOffset = IndexBufferByteOff | (m_IndexBufferByteOffset & 0x10000000);
82 }
83
84 void AddIndexBufferByteOffset(offset_ptr32 IndexBufferByteOff)
85 {
86 m_IndexBufferByteOffset = ((m_IndexBufferByteOffset & 0xEFFFFFFF) + IndexBufferByteOff) | (m_IndexBufferByteOffset & 0x10000000);
87 }
88 };
89 STileVisual *m_pTilesOfLayer;
90
91 STileVisual m_BorderTopLeft;
92 STileVisual m_BorderTopRight;
93 STileVisual m_BorderBottomRight;
94 STileVisual m_BorderBottomLeft;
95
96 STileVisual m_BorderKillTile; //end of map kill tile -- game layer only
97
98 std::vector<STileVisual> m_vBorderTop;
99 std::vector<STileVisual> m_vBorderLeft;
100 std::vector<STileVisual> m_vBorderRight;
101 std::vector<STileVisual> m_vBorderBottom;
102
103 unsigned int m_Width;
104 unsigned int m_Height;
105 int m_BufferContainerIndex;
106 bool m_IsTextured;
107 };
108 std::vector<STileLayerVisuals *> m_vpTileLayerVisuals;
109
110 struct SQuadLayerVisuals
111 {
112 SQuadLayerVisuals() :
113 m_QuadNum(0), m_pQuadsOfLayer(nullptr), m_BufferContainerIndex(-1), m_IsTextured(false) {}
114
115 struct SQuadVisual
116 {
117 SQuadVisual() :
118 m_IndexBufferByteOffset(0) {}
119
120 offset_ptr m_IndexBufferByteOffset;
121 };
122
123 int m_QuadNum;
124 SQuadVisual *m_pQuadsOfLayer;
125
126 int m_BufferContainerIndex;
127 bool m_IsTextured;
128 };
129 std::vector<SQuadLayerVisuals *> m_vpQuadLayerVisuals;
130
131 virtual CCamera *GetCurCamera();
132
133 void LayersOfGroupCount(CMapItemGroup *pGroup, int &TileLayerCount, int &QuadLayerCount, bool &PassedGameLayer);
134
135protected:
136 virtual bool CanRenderMenuBackground() { return true; }
137
138public:
139 enum
140 {
141 TYPE_BACKGROUND = 0,
142 TYPE_BACKGROUND_FORCE,
143 TYPE_FOREGROUND,
144 TYPE_FULL_DESIGN,
145 TYPE_ALL = -1,
146 };
147
148 CMapLayers(int Type, bool OnlineOnly = true);
149 virtual ~CMapLayers();
150 virtual int Sizeof() const override { return sizeof(*this); }
151 virtual void OnInit() override;
152 virtual void OnRender() override;
153 virtual void OnMapLoad() override;
154
155 void RenderTileLayer(int LayerIndex, const ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup);
156 void RenderTileBorder(int LayerIndex, const ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup, int BorderX0, int BorderY0, int BorderX1, int BorderY1);
157 void RenderKillTileBorder(int LayerIndex, const ColorRGBA &Color, CMapItemLayerTilemap *pTileLayer, CMapItemGroup *pGroup);
158 void RenderQuadLayer(int LayerIndex, CMapItemLayerQuads *pQuadLayer, CMapItemGroup *pGroup, bool ForceRender = false);
159
160 void EnvelopeUpdate();
161
162 static void EnvelopeEval(int TimeOffsetMillis, int Env, ColorRGBA &Result, size_t Channels, void *pUser);
163};
164
165#endif
166