hud_system.cpp 4.1 KB
Newer Older
1
2
3
#include "hud_system.hpp"

#include <imgui_internal.h>
Florian Oetke's avatar
Florian Oetke committed
4
#include <glm/glm.hpp>
5
6
7
8
9
10
11
12
13
14
15
#include <glm/vec2.hpp>
#include <glm/vec4.hpp>

#include <string>
#include <unordered_map>

namespace phase_shifter::ui {

	using namespace mirrage::gui::literals;

	namespace {
Florian Oetke's avatar
Florian Oetke committed
16
		constexpr auto hud_height      = 130;
17
18
		constexpr auto bar_height      = 80;
		constexpr auto beat_bar_height = 79;
Florian Oetke's avatar
Florian Oetke committed
19
		constexpr auto bar_speed       = 100;
20
		constexpr auto beat_bar_length = 600.0f;
Kevin Balz's avatar
Kevin Balz committed
21
	} // namespace
22

Kevin Balz's avatar
Kevin Balz committed
23
24
	Hud_system::Hud_system(mirrage::gui::Gui&                          gui,
	                       mirrage::ecs::Entity_manager&               ecs,
25
	                       const phase_shifter::gameplay::Beat_system& beat_system)
26
	  : _gui(gui), _ecs(ecs), _beat_system(beat_system)
27
	{
Kevin Balz's avatar
Kevin Balz committed
28
		//_circle_texture = _gui.load_texture("tex:circle"_aid);
29
30
	}

31
	void Hud_system::update(mirrage::util::Time dt) { _passed += dt.value(); }
32
33
34
35
36
37
38
39
40

	void Hud_system::draw()
	{
		auto viewport = _gui.viewport();
		auto font     = _gui.find_font("default"_strid);

		if(font.is_some())
			ImGui::PushFont(font.get_or_throw());

Florian Oetke's avatar
Florian Oetke committed
41
42
		ImGui::PushStyleColor(ImGuiCol_WindowBg, ImColor(0, 0, 0, 180).Value);
		ImGui::PushStyleColor(ImGuiCol_Border, ImColor(0, 0, 0, 0).Value);
Florian Oetke's avatar
Florian Oetke committed
43
44
45
		ImGui::PositionNextWindow(glm::vec2(viewport.z, hud_height),
		                          ImGui::WindowPosition_X::center,
		                          ImGui::WindowPosition_Y::bottom);
46
47
		if(ImGui::Begin("beat",
		                nullptr,
Kevin Balz's avatar
Kevin Balz committed
48
		                ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize
Florian Oetke's avatar
Florian Oetke committed
49
		                        | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoScrollbar)) {
Kevin Balz's avatar
Kevin Balz committed
50
			ImGui::PushStyleColor(ImGuiCol_Border, "#00000000"_imcolor.Value); // Hide Border
Florian Oetke's avatar
Florian Oetke committed
51
			ImVec2 cursor = ImGui::GetCursorScreenPos();
Florian Oetke's avatar
Florian Oetke committed
52
			cursor.y += hud_height / 2.f + 10;
53
54
55
			auto beat_state = _beat_system.beat_state();
			auto beats      = _beat_system.time_stamps();
			auto beat_index = _beat_system.beat_index() + 1;
56
57
			//auto line_offset = bar_speed * beat_state.avg_beat_time;
			//auto beats       = std::clamp(beat_state.beats_left, 0, 5);
Florian Oetke's avatar
Florian Oetke committed
58
			ImGui::BeginChild("Line", {viewport.z, hud_height}, true);
59
			ImDrawList* drawList = ImGui::GetWindowDrawList();
Kevin Balz's avatar
Kevin Balz committed
60
			
Kevin Balz's avatar
Kevin Balz committed
61
			while (beat_index < static_cast<int>(beats.size())) {
62
				auto x_offset = (beats[beat_index] - _passed) * bar_speed;
Kevin Balz's avatar
tweaks    
Kevin Balz committed
63
64
65
				if(x_offset > beat_bar_length) {
					break;
				}
66
				auto height   = beat_bar_height * (1.f - glm::smoothstep(0.f, beat_bar_length, x_offset));
Kevin Balz's avatar
tweaks    
Kevin Balz committed
67
68
69
70
				float alpha    = 1 - (x_offset / beat_bar_length);
				auto bar_color_float = beat_index < static_cast<int>(beats.size() * 0.8f) ? ImVec4(1, 1, 1, alpha)
				                                                       : ImVec4(1, 0, 0, alpha);
				auto bar_color = ImGui::ColorConvertFloat4ToU32(bar_color_float);
Kevin Balz's avatar
Kevin Balz committed
71

Florian Oetke's avatar
Florian Oetke committed
72
				ImVec2 p(cursor.x + viewport.z / 2 - x_offset, cursor.y - height / 2.f);
Florian Oetke's avatar
Florian Oetke committed
73
				drawList->AddLine(p, {p.x, p.y + height}, bar_color, 2);
Florian Oetke's avatar
Florian Oetke committed
74
75

				p.x = cursor.x + viewport.z / 2 + x_offset;
Florian Oetke's avatar
Florian Oetke committed
76
				drawList->AddLine(p, {p.x, p.y + height}, bar_color, 2);
Kevin Balz's avatar
tweaks    
Kevin Balz committed
77
				
78
				beat_index++;
Kevin Balz's avatar
Kevin Balz committed
79
			}
Florian Oetke's avatar
Florian Oetke committed
80
81

			ImVec2 middle(cursor.x + viewport.z / 2, cursor.y - bar_height / 2.f);
Florian Oetke's avatar
Florian Oetke committed
82
83
84
85
86
87
88
89
90
91
92
93
			drawList->AddLine(middle, {middle.x, middle.y + bar_height}, 0xFFFF0000, 6);

			auto beat_color = (_beat_system.beat_state().beats_left < 50
			                   && _beat_system.beat_state().beats_left % 2 == 0)
			                          ? ImColor(255, 0, 0)
			                          : ImColor(255, 255, 255);

			auto beats_left = std::to_string(_beat_system.beat_state().beats_left);
			auto text_size  = ImGui::CalcTextSize(beats_left.c_str());
			drawList->AddText(ImVec2(middle.x - text_size.x / 2.f, middle.y - text_size.y - 10),
			                  beat_color,
			                  beats_left.c_str());
Florian Oetke's avatar
Florian Oetke committed
94

95
			ImGui::EndChild();
Kevin Balz's avatar
Kevin Balz committed
96
97
			ImGui::PopStyleColor();

98
99

			ImGui::End();
Kevin Balz's avatar
Kevin Balz committed
100
101
102
103
104
105

			if(beat_state.beat || beat_state.avg_beat_time - beat_state.time_since_beat < 0.1f
			   || beat_state.time_to_beat < 0.1f) {
				//TODO: Flash image to beat
				//ImGui::Image(_circle_texture.get(), {10, 10});
			}
106
107
		}

Florian Oetke's avatar
Florian Oetke committed
108
109
110
		ImGui::PopStyleColor();
		ImGui::PopStyleColor();

111
112
113
114
115
		if(font.is_some())
			ImGui::PopFont();
	}

} // namespace phase_shifter::ui