Antkeeper  0.0.1
graphics-menu-state.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
22 #include "game/controls.hpp"
23 #include <engine/scene/text.hpp>
24 #include <engine/debug/log.hpp>
25 #include "game/fonts.hpp"
26 #include "game/menu.hpp"
27 #include "game/graphics.hpp"
29 #include "game/strings.hpp"
31 
32 using namespace hash::literals;
33 
34 
36  game_state(ctx)
37 {
38  debug::log_trace("Entering graphics menu state...");
39 
40  // Construct menu item texts
41  fullscreen_name_text = std::make_unique<scene::text>();
42  fullscreen_value_text = std::make_unique<scene::text>();
43  resolution_name_text = std::make_unique<scene::text>();
44  resolution_value_text = std::make_unique<scene::text>();
45  v_sync_name_text = std::make_unique<scene::text>();
46  v_sync_value_text = std::make_unique<scene::text>();
47  aa_method_name_text = std::make_unique<scene::text>();
48  aa_method_value_text = std::make_unique<scene::text>();
49  font_scale_name_text = std::make_unique<scene::text>();
50  font_scale_value_text = std::make_unique<scene::text>();
51  dyslexia_font_name_text = std::make_unique<scene::text>();
52  dyslexia_font_value_text = std::make_unique<scene::text>();
53  back_text = std::make_unique<scene::text>();
54 
55  // Build list of menu item texts
56  ctx.menu_item_texts.push_back({fullscreen_name_text.get(), fullscreen_value_text.get()});
57  ctx.menu_item_texts.push_back({resolution_name_text.get(), resolution_value_text.get()});
58  ctx.menu_item_texts.push_back({v_sync_name_text.get(), v_sync_value_text.get()});
59  ctx.menu_item_texts.push_back({aa_method_name_text.get(), aa_method_value_text.get()});
60  ctx.menu_item_texts.push_back({font_scale_name_text.get(), font_scale_value_text.get()});
61  ctx.menu_item_texts.push_back({dyslexia_font_name_text.get(), dyslexia_font_value_text.get()});
62  ctx.menu_item_texts.push_back({back_text.get(), nullptr});
63 
64  // Set content of menu item texts
65  fullscreen_name_text->set_content(get_string(ctx, "graphics_menu_fullscreen"));
66  resolution_name_text->set_content(get_string(ctx, "graphics_menu_resolution"));
67  v_sync_name_text->set_content(get_string(ctx, "graphics_menu_v_sync"));
68  aa_method_name_text->set_content(get_string(ctx, "graphics_menu_aa_method"));
69  font_scale_name_text->set_content(get_string(ctx, "graphics_menu_font_scale"));
70  dyslexia_font_name_text->set_content(get_string(ctx, "graphics_menu_dyslexia_font"));
71  back_text->set_content(get_string(ctx, "back"));
72  update_value_text_content();
73 
74  // Init menu item index
75  ::menu::init_menu_item_index(ctx, "graphics");
76 
82 
83  // Construct menu item callbacks
84  auto toggle_fullscreen_callback = [this, &ctx]()
85  {
86  bool fullscreen = !ctx.window->is_fullscreen();
87 
88  ctx.window->set_fullscreen(fullscreen);
89 
90  this->update_value_text_content();
92 
93  // Update fullscreen settings
94  (*ctx.settings)["fullscreen"] = fullscreen;
95  };
96 
97  auto increase_resolution_callback = [this, &ctx]()
98  {
99  // Increase resolution
101  ctx.render_scale += 0.05f;
102  else
103  ctx.render_scale += 0.25f;
104 
105  // Limit resolution
106  if (ctx.render_scale > 2.0f)
107  ctx.render_scale = 2.0f;
108 
109  // Update render scale setting
110  (*ctx.settings)["render_scale"] = ctx.render_scale;
111 
112  // Resize framebuffers
114 
115  // Update text
116  this->update_value_text_content();
118  };
119 
120  auto decrease_resolution_callback = [this, &ctx]()
121  {
122  // Increase resolution
124  ctx.render_scale -= 0.05f;
125  else
126  ctx.render_scale -= 0.25f;
127 
128  // Limit resolution
129  if (ctx.render_scale < 0.25f)
130  ctx.render_scale = 0.25f;
131 
132  // Update render scale setting
133  (*ctx.settings)["render_scale"] = ctx.render_scale;
134 
135  // Resize framebuffers
137 
138  // Update text
139  this->update_value_text_content();
141  };
142 
143  auto toggle_v_sync_callback = [this, &ctx]()
144  {
145  bool v_sync = !ctx.window->get_v_sync();
146 
147  // Update v-sync setting
148  (*ctx.settings)["v_sync"] = v_sync;
149 
150  ctx.window->set_v_sync(v_sync);
151 
152  this->update_value_text_content();
154  };
155 
156  auto next_aa_method_callback = [this, &ctx]()
157  {
158  switch (ctx.anti_aliasing_method)
159  {
162  break;
163 
166  break;
167  }
168 
169  // Update anti-aliasing method setting
170  (*ctx.settings)["anti_aliasing_method"] = std::to_underlying(ctx.anti_aliasing_method);
171 
173 
174  // Update value text
175  this->update_value_text_content();
176 
177  // Refresh and realign text
180  };
181 
182  auto previous_aa_method_callback = [this, &ctx]()
183  {
184  switch (ctx.anti_aliasing_method)
185  {
188  break;
189 
192  break;
193  }
194 
195  // Update anti-aliasing method setting
196  (*ctx.settings)["anti_aliasing_method"] = std::to_underlying(ctx.anti_aliasing_method);
197 
199 
200  // Update value text
201  this->update_value_text_content();
202 
203  // Refresh and realign text
206  };
207 
208  auto increase_font_scale_callback = [this, &ctx]()
209  {
210  // Increase font scale
212  ctx.font_scale += 0.01f;
213  else
214  ctx.font_scale += 0.1f;
215 
216  // Limit font scale
217  if (ctx.font_scale > 2.0f)
218  ctx.font_scale = 2.0f;
219 
220  // Update font scale setting
221  (*ctx.settings)["font_scale"] = ctx.font_scale;
222 
223  // Update value text
224  this->update_value_text_content();
225 
226  // Reload fonts
227  debug::log_trace("Reloading fonts...");
228  ::load_fonts(ctx);
229  debug::log_trace("Reloaded fonts");
230 
231  // Refresh and realign text
234  };
235 
236  auto decrease_font_scale_callback = [this, &ctx]()
237  {
238  // Decrease font scale
240  ctx.font_scale -= 0.01f;
241  else
242  ctx.font_scale -= 0.1f;
243 
244  // Limit font scale
245  if (ctx.font_scale < 0.1f)
246  ctx.font_scale = 0.1f;
247 
248  // Update font scale setting
249  (*ctx.settings)["font_scale"] = ctx.font_scale;
250 
251  // Update value text
252  this->update_value_text_content();
253 
254  // Reload fonts
255  debug::log_trace("Reloading fonts...");
256  ::load_fonts(ctx);
257  debug::log_trace("Reloaded fonts");
258 
259  // Refresh and realign text
262  };
263 
264  auto toggle_dyslexia_font_callback = [this, &ctx]()
265  {
267 
268  // Update value text
269  this->update_value_text_content();
270 
271  // Save dyslexia font setting
272  (*ctx.settings)["dyslexia_font"] = ctx.dyslexia_font;
273 
274  // Reload fonts
275  debug::log_trace("Reloading fonts...");
276  ::load_fonts(ctx);
277  debug::log_trace("Reloaded fonts");
278 
279  // Refresh and realign text
282  };
283  auto select_back_callback = [&ctx]()
284  {
285  // Disable menu controls
286  ctx.function_queue.push(std::bind(::disable_menu_controls, std::ref(ctx)));
287 
289  (
290  ctx,
291  [&ctx]()
292  {
293  // Queue change to options menu state
294  ctx.function_queue.push
295  (
296  [&ctx]()
297  {
298  ctx.state_machine.pop();
299  ctx.state_machine.emplace(std::make_unique<options_menu_state>(ctx));
300  }
301  );
302  }
303  );
304  };
305 
306  // Build list of menu select callbacks
307  ctx.menu_select_callbacks.push_back(toggle_fullscreen_callback);
308  ctx.menu_select_callbacks.push_back(increase_resolution_callback);
309  ctx.menu_select_callbacks.push_back(toggle_v_sync_callback);
310  ctx.menu_select_callbacks.push_back(next_aa_method_callback);
311  ctx.menu_select_callbacks.push_back(increase_font_scale_callback);
312  ctx.menu_select_callbacks.push_back(toggle_dyslexia_font_callback);
313  ctx.menu_select_callbacks.push_back(select_back_callback);
314 
315  // Build list of menu left callbacks
316  ctx.menu_left_callbacks.push_back(toggle_fullscreen_callback);
317  ctx.menu_left_callbacks.push_back(decrease_resolution_callback);
318  ctx.menu_left_callbacks.push_back(toggle_v_sync_callback);
319  ctx.menu_left_callbacks.push_back(previous_aa_method_callback);
320  ctx.menu_left_callbacks.push_back(decrease_font_scale_callback);
321  ctx.menu_left_callbacks.push_back(toggle_dyslexia_font_callback);
322  ctx.menu_left_callbacks.push_back(nullptr);
323 
324  // Build list of menu right callbacks
325  ctx.menu_right_callbacks.push_back(toggle_fullscreen_callback);
326  ctx.menu_right_callbacks.push_back(increase_resolution_callback);
327  ctx.menu_right_callbacks.push_back(toggle_v_sync_callback);
328  ctx.menu_right_callbacks.push_back(next_aa_method_callback);
329  ctx.menu_right_callbacks.push_back(increase_font_scale_callback);
330  ctx.menu_right_callbacks.push_back(toggle_dyslexia_font_callback);
331  ctx.menu_right_callbacks.push_back(nullptr);
332 
333  // Set menu back callback
334  ctx.menu_back_callback = select_back_callback;
335 
336  // Enable menu controls next frame
337  ctx.function_queue.push(std::bind(::enable_menu_controls, std::ref(ctx)));
338 
339  // Fade in menu
340  ::menu::fade_in(ctx, nullptr);
341 
342  debug::log_trace("Entered graphics menu state");
343 }
344 
346 {
347  debug::log_trace("Exiting graphics menu state...");
348 
349  // Destruct menu
355 
356  debug::log_trace("Exited graphics menu state");
357 }
358 
359 void graphics_menu_state::update_value_text_content()
360 {
361  const bool fullscreen = ctx.window->is_fullscreen();
362  const float render_scale = ctx.render_scale;
363  const bool v_sync = ctx.window->get_v_sync();
364  const int aa_method_index = static_cast<int>(ctx.anti_aliasing_method);
365  const float font_scale = ctx.font_scale;
366  const bool dyslexia_font = ctx.dyslexia_font;
367 
368  const std::string string_on = get_string(ctx, "on");
369  const std::string string_off = get_string(ctx, "off");
370 
371  /*
372  const std::string string_quality[4] =
373  {
374  (*ctx.strings)["off"],
375  (*ctx.strings)["quality_low"],
376  (*ctx.strings)["quality_medium"],
377  (*ctx.strings)["quality_high"]
378  };
379  */
380 
381  const std::string string_aa_methods[2] =
382  {
383  get_string(ctx, "graphics_menu_aa_method_none"),
384  get_string(ctx, "graphics_menu_aa_method_fxaa")
385  };
386 
387  std::get<1>(ctx.menu_item_texts[0])->set_content((fullscreen) ? string_on : string_off);
388  std::get<1>(ctx.menu_item_texts[1])->set_content(std::to_string(static_cast<int>(std::round(render_scale * 100.0f))) + "%");
389  std::get<1>(ctx.menu_item_texts[2])->set_content((v_sync) ? string_on : string_off);
390  std::get<1>(ctx.menu_item_texts[3])->set_content(string_aa_methods[aa_method_index]);
391  std::get<1>(ctx.menu_item_texts[4])->set_content(std::to_string(static_cast<int>(std::round(font_scale * 100.0f))) + "%");
392  std::get<1>(ctx.menu_item_texts[5])->set_content((dyslexia_font) ? string_on : string_off);
393 }
Abstract base class for game states.
Definition: game-state.hpp:29
::game & ctx
Definition: game-state.hpp:44
Definition: game.hpp:121
std::vector< std::function< void()> > menu_left_callbacks
Definition: game.hpp:348
input::action menu_modifier_action
Definition: game.hpp:211
std::vector< std::function< void()> > menu_right_callbacks
Definition: game.hpp:349
hsm::state_machine< game_state > state_machine
Definition: game.hpp:299
float render_scale
Definition: game.hpp:318
std::vector< std::function< void()> > menu_select_callbacks
Definition: game.hpp:347
float font_scale
Definition: game.hpp:341
render::anti_aliasing_method anti_aliasing_method
Definition: game.hpp:427
std::shared_ptr< dict< hash::fnv1a32_t > > settings
Definition: game.hpp:162
std::vector< std::tuple< scene::text *, scene::text * > > menu_item_texts
Definition: game.hpp:351
std::shared_ptr< app::window > window
Definition: game.hpp:166
std::queue< std::function< void()> > function_queue
Definition: game.hpp:303
bool dyslexia_font
Definition: game.hpp:342
std::function< void()> menu_back_callback
Definition: game.hpp:350
graphics_menu_state(::game &ctx)
bool is_active() const noexcept
Returns true if the action is active, false otherwise.
Definition: action.hpp:79
void load_fonts(::game &ctx)
Definition: fonts.cpp:64
void enable_menu_controls(::game &ctx)
void disable_menu_controls(::game &ctx)
log_message< log_message_severity::trace, Args... > log_trace
Formats and logs a trace message.
Definition: log.hpp:88
void select_anti_aliasing_method(::game &ctx, render::anti_aliasing_method method)
Definition: graphics.cpp:320
void change_render_resolution(::game &ctx, float scale)
Definition: graphics.cpp:249
User-defined literals for compile-time string hashing.
Definition: fnv1a.hpp:232
constexpr vector< T, N > round(const vector< T, N > &x)
Performs a element-wise round operation.
Definition: vector.hpp:1489
void init_menu_item_index(::game &ctx, hash::fnv1a32_t menu_name)
Definition: menu.cpp:31
void update_text_color(::game &ctx)
Definition: menu.cpp:59
void clear_callbacks(::game &ctx)
Definition: menu.cpp:197
void delete_animations(::game &ctx)
Definition: menu.cpp:191
void align_text(::game &ctx, bool center, bool has_back, float anchor_y)
Definition: menu.cpp:73
void setup_animations(::game &ctx)
Definition: menu.cpp:206
void refresh_text(::game &ctx)
Definition: menu.cpp:156
void add_text_to_ui(::game &ctx)
Definition: menu.cpp:166
void fade_out(::game &ctx, const std::function< void()> &end_callback)
Definition: menu.cpp:263
void update_text_font(::game &ctx)
Definition: menu.cpp:44
void fade_in(::game &ctx, const std::function< void()> &end_callback)
Definition: menu.cpp:233
void remove_text_from_ui(::game &ctx)
Definition: menu.cpp:176
void delete_text(::game &ctx)
Definition: menu.cpp:186
@ none
No anti-aliasing.
@ fxaa
Fast approximate anti-aliasing (FXAA).
std::string get_string(const ::game &ctx, hash::fnv1a32_t key)
Returns a localized string.
Definition: strings.cpp:23
Self-formatting message that logs itself to the default logger on construction.
Definition: log.hpp:53