File: InGameMenu.h

package info (click to toggle)
jazz2-native 3.5.0-1
  • links: PTS, VCS
  • area: contrib
  • in suites:
  • size: 16,836 kB
  • sloc: cpp: 172,557; xml: 113; python: 36; makefile: 5; sh: 2
file content (166 lines) | stat: -rw-r--r-- 5,847 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#pragma once

#include "IMenuContainer.h"
#include "MenuSection.h"
#include "../../LevelHandler.h"
#include "../Canvas.h"
#include "../../ContentResolver.h"

#include "../../../nCine/Input/InputEvents.h"
#include "../../../nCine/Audio/AudioBufferPlayer.h"

using namespace Jazz2::Tiles;

namespace Jazz2::UI::Menu
{
	/** @brief In-game menu */
	class InGameMenu : public IMenuContainer
	{
		DEATH_RUNTIME_OBJECT(IMenuContainer);

	public:
		/** @{ @name Constants */

		/** @brief Default width of viewport */
		static constexpr std::int32_t DefaultWidth = 720;
		/** @brief Default height of viewport */
		static constexpr std::int32_t DefaultHeight = 405;

		/** @} */

		InGameMenu(LevelHandler* root);
		~InGameMenu();

		/** @brief Called when a key is pressed */
		void OnKeyPressed(const nCine::KeyboardEvent& event);
		/** @brief Called when a key is released */
		void OnKeyReleased(const nCine::KeyboardEvent& event);
		/** @brief Called when a touch event is triggered */
		void OnTouchEvent(const nCine::TouchEvent& event);
		/** @brief Called when the viewport needs to be initialized (e.g., when the resolution is changed) */
		void OnInitializeViewport(std::int32_t width, std::int32_t height);

		MenuSection* SwitchToSectionDirect(std::unique_ptr<MenuSection> section) override;
		void LeaveSection() override;
		MenuSection* GetCurrentSection() const override;
		MenuSection* GetUnderlyingSection() const override;
		void ChangeLevel(LevelInitialization&& levelInit) override;
		bool HasResumableState() const override;
		void ResumeSavedState() override;
#if defined(WITH_MULTIPLAYER) || defined(DOXYGEN_GENERATING_OUTPUT)
		void ConnectToServer(StringView endpoint, std::uint16_t defaultPort) override;
		bool CreateServer(Jazz2::Multiplayer::ServerInitialization&& serverInit) override;
#endif
		void ApplyPreferencesChanges(ChangedPreferencesType type) override;
		bool ActionPressed(PlayerAction action) override;
		bool ActionHit(PlayerAction action) override;

		Vector2i GetViewSize() const override {
			return _canvasBackground->ViewSize;
		}

		Recti GetContentBounds() const override {
			return _contentBounds;
		}

		void DrawElement(AnimState state, std::int32_t frame, float x, float y, std::uint16_t z, Alignment align, const Colorf& color,
			float scaleX = 1.0f, float scaleY = 1.0f, bool additiveBlending = false, bool unaligned = false) override;
		void DrawElement(AnimState state, float x, float y, std::uint16_t z, Alignment align, const Colorf& color,
			Vector2f size, const Vector4f& texCoords, bool unaligned = false) override;
		void DrawSolid(float x, float y, std::uint16_t z, Alignment align, Vector2f size, const Colorf& color, bool additiveBlending = false) override;
		void DrawTexture(const Texture& texture, float x, float y, std::uint16_t z, Alignment align, Vector2f size, const Colorf& color, bool unaligned = false) override;
		Vector2f MeasureString(StringView text, float scale = 1.0f, float charSpacing = 1.0f, float lineSpacing = 1.0f) override;
		void DrawStringShadow(StringView text, std::int32_t& charOffset, float x, float y, std::uint16_t z, Alignment align, const Colorf& color,
			float scale = 1.0f, float angleOffset = 0.0f, float varianceX = 4.0f, float varianceY = 4.0f,
			float speed = 0.4f, float charSpacing = 1.0f, float lineSpacing = 1.0f) override;
		void DrawStringGlow(StringView text, std::int32_t& charOffset, float x, float y, std::uint16_t z, Alignment align, const Colorf& color,
			float scale = 1.0f, float angleOffset = 0.0f, float varianceX = 4.0f, float varianceY = 4.0f,
			float speed = 0.4f, float charSpacing = 1.0f, float lineSpacing = 1.0f) override;
		void PlaySfx(StringView identifier, float gain = 1.0f) override;

		/** @brief Returns `true` if the level handler is on a local session */
		bool IsLocalSession() const;
		/** @brief Hides the in-game menu and resumes paused game */
		void ResumeGame();
		/** @brief Leaves the paused game and switches back to the main menu */
		void GoToMainMenu();

	private:
		LevelHandler* _root;

		enum class ActiveCanvas {
			Background,
			Clipped,
			Overlay
		};

#ifndef DOXYGEN_GENERATING_OUTPUT
		// Doxygen 1.12.0 outputs also private structs/unions even if it shouldn't
		class MenuBackgroundCanvas : public Canvas
		{
		public:
			MenuBackgroundCanvas(InGameMenu* owner) : _owner(owner) { }

			void OnUpdate(float timeMult) override;
			bool OnDraw(RenderQueue& renderQueue) override;

		private:
			InGameMenu* _owner;

			void DrawViewportSeparators();
		};

		class MenuClippedCanvas : public Canvas
		{
		public:
			MenuClippedCanvas(InGameMenu* owner) : _owner(owner) { }

			bool OnDraw(RenderQueue& renderQueue) override;

		private:
			InGameMenu* _owner;
		};

		class MenuOverlayCanvas : public Canvas
		{
		public:
			MenuOverlayCanvas(InGameMenu* owner) : _owner(owner) { }

			bool OnDraw(RenderQueue& renderQueue) override;

		private:
			InGameMenu* _owner;
		};
#endif

		Recti _contentBounds;
		std::unique_ptr<MenuBackgroundCanvas> _canvasBackground;
		std::unique_ptr<MenuClippedCanvas> _canvasClipped;
		std::unique_ptr<MenuOverlayCanvas> _canvasOverlay;
		ActiveCanvas _activeCanvas;
		Metadata* _metadata;
		Font* _smallFont;
		Font* _mediumFont;
#if defined(WITH_AUDIO)
		SmallVector<std::shared_ptr<AudioBufferPlayer>> _playingSounds;
#endif

		SmallVector<std::unique_ptr<MenuSection>, 8> _sections;
		std::uint32_t _pressedActions;
		NavigationFlags _lastNavigationFlags;
		float _touchButtonsTimer;

		void UpdateContentBounds(Vector2i viewSize);
		void UpdatePressedActions();

		inline Canvas* GetActiveCanvas()
		{
			switch (_activeCanvas) {
				default:
				case ActiveCanvas::Background: return _canvasBackground.get();
				case ActiveCanvas::Clipped: return _canvasClipped.get();
				case ActiveCanvas::Overlay: return _canvasOverlay.get();
			}
		}
	};
}