59 #include <engine/config.hpp>
89 #include <entt/entt.hpp>
98 #define CXXOPTS_NO_RTTI
99 #include <cxxopts.hpp>
110 auto boot_t0 = std::chrono::high_resolution_clock::now();
113 parse_options(argc, argv);
131 active_ecoregion =
nullptr;
136 auto boot_t1 = std::chrono::high_resolution_clock::now();
143 debug::log_info(
"Boot duration: {}", std::chrono::duration_cast<std::chrono::duration<double>>(boot_t1 - boot_t0));
158 const auto& windowed_position = window->get_windowed_position();
159 const auto& windowed_size = window->get_windowed_size();
160 const bool maximized = window->is_maximized();
161 const bool fullscreen = window->is_fullscreen();
162 (*settings)[
"window_x"] = windowed_position.x();
163 (*settings)[
"window_y"] = windowed_position.y();
164 (*settings)[
"window_w"] = windowed_size.x();
165 (*settings)[
"window_h"] = windowed_size.y();
166 (*settings)[
"maximized"] = maximized;
167 (*settings)[
"fullscreen"] = fullscreen;
177 input_manager.reset();
178 window_manager.reset();
186 void game::parse_options(
int argc,
const char*
const* argv)
199 cxxopts::Options options(config::application_name, config::application_name);
200 options.add_options()
201 (
"c,continue",
"Continues from the last save")
202 (
"d,data",
"Sets the data package path", cxxopts::value<std::string>())
203 (
"f,fullscreen",
"Starts in fullscreen mode")
204 (
"n,new-game",
"Starts a new game")
205 (
"q,quick-start",
"Skips to the main menu")
206 (
"r,reset",
"Resets all settings to default")
207 (
"v,v-sync",
"Enables or disables v-sync", cxxopts::value<int>())
208 (
"w,windowed",
"Starts in windowed mode");
209 auto result = options.parse(argc, argv);
212 if (result.count(
"continue"))
214 option_continue =
true;
218 if (result.count(
"data"))
220 option_data = result[
"data"].as<std::string>();
224 if (result.count(
"fullscreen"))
226 option_fullscreen =
true;
230 if (result.count(
"new-game"))
232 option_new_game =
true;
236 if (result.count(
"quick-start"))
238 option_quick_start =
true;
242 if (result.count(
"reset"))
248 if (result.count(
"v-sync"))
250 option_v_sync = result[
"v-sync"].as<
int>();
254 if (result.count(
"windowed"))
256 option_windowed =
true;
261 catch (
const std::exception& e)
263 debug::log_error(
"An error occurred while parsing command-line options: {}",
e.what());
267 void game::setup_resources()
279 data_package_path = option_data.value();
280 if (data_package_path.is_relative())
282 data_package_path = data_path / data_package_path;
287 data_package_path = data_path / (config::application_slug + std::string(
"-data.zip"));
291 mods_path = data_path /
"mods";
296 saves_path = shared_config_path /
"saves";
297 screenshots_path = shared_config_path /
"gallery";
298 controls_path = shared_config_path /
"controls";
301 debug::log_info(
"Data package path: \"{}\"", data_package_path.string());
302 debug::log_info(
"Local config path: \"{}\"", local_config_path.string());
303 debug::log_info(
"Shared config path: \"{}\"", shared_config_path.string());
307 std::vector<std::filesystem::path> config_paths;
308 config_paths.push_back(local_config_path);
309 config_paths.push_back(shared_config_path);
310 config_paths.push_back(saves_path);
311 config_paths.push_back(screenshots_path);
312 config_paths.push_back(controls_path);
313 for (
const auto& path: config_paths)
317 if (std::filesystem::create_directories(path))
322 catch (
const std::filesystem::filesystem_error& e)
324 debug::log_error(
"Failed to create directory \"{}\": {}", path.string(),
e.what());
329 std::vector<std::filesystem::path> mod_paths;
330 if (std::filesystem::is_directory(mods_path))
332 for (
const auto& entry: std::filesystem::directory_iterator{mods_path})
334 if (entry.is_directory() || (entry.is_regular_file() && entry.path().extension() ==
".zip"))
336 mod_paths.push_back(entry.path());
343 for (
const std::filesystem::path& mod_path: mod_paths)
359 void game::load_settings()
364 settings = std::make_shared<dict<hash::fnv1a32_t>>();
375 settings = std::make_shared<dict<hash::fnv1a32_t>>();
380 void game::setup_window()
386 std::string window_title = config::application_name;
391 bool maximized =
true;
392 bool fullscreen =
true;
412 const app::display& display = window_manager->get_display(0);
414 const auto usable_bounds_center = usable_bounds.center();
416 const float default_windowed_scale = 1.0f / 1.2f;
418 window_w =
static_cast<int>((usable_bounds.max.x() - usable_bounds.min.x()) * default_windowed_scale);
419 window_h =
static_cast<int>((usable_bounds.max.y() - usable_bounds.min.y()) * default_windowed_scale);
420 window_x = usable_bounds_center.x() - window_w / 2;
421 window_y = usable_bounds_center.y() - window_h / 2;
431 if (option_fullscreen)
438 v_sync = option_v_sync.value();
442 window = window_manager->create_window
445 {window_x, window_y},
446 {window_w, window_h},
453 window->set_minimum_size({160, 144});
456 window_closed_subscription = window->get_closed_channel().subscribe
458 [&](
const auto&
event)
465 void game::setup_audio()
470 master_volume = 1.0f;
471 ambience_volume = 1.0f;
472 effects_volume = 1.0f;
475 captions_size = 1.0f;
487 alc_device = alcOpenDevice(
nullptr);
490 debug::log_error(
"Failed to open audio device: AL error code {}", alGetError());
496 const ALCchar* alc_device_name =
nullptr;
497 if (alcIsExtensionPresent(alc_device,
"ALC_ENUMERATE_ALL_EXT"))
499 alc_device_name = alcGetString(alc_device, ALC_ALL_DEVICES_SPECIFIER);
501 if (alcGetError(alc_device) != AL_NO_ERROR || !alc_device_name)
503 alc_device_name = alcGetString(alc_device, ALC_DEVICE_SPECIFIER);
512 alc_context = alcCreateContext(alc_device,
nullptr);
515 debug::log_error(
"Failed to create audio context: ALC error code {}", alcGetError(alc_device));
516 alcCloseDevice(alc_device);
526 if (alcMakeContextCurrent(alc_context) == ALC_FALSE)
528 debug::log_error(
"Failed to make audio context current: ALC error code {}", alcGetError(alc_device));
529 if (alc_context !=
nullptr)
531 alcDestroyContext(alc_context);
533 alcCloseDevice(alc_device);
544 void game::setup_input()
550 input_manager->update();
555 [&](
const auto&
event)
625 void game::load_strings()
636 std::string language_slug = language_tag;
639 language_slug.begin(),
641 language_slug.begin(),
644 return std::tolower(c);
655 const std::string window_title =
get_string(*
this,
"window_title");
656 window->set_title(window_title);
659 (*settings)[
"window_title"] = window_title;
664 void game::setup_rendering()
671 shadow_map_resolution = 4096;
687 bloom_pass = std::make_unique<render::bloom_pass>(&window->get_graphics_pipeline(),
resource_manager.get());
688 bloom_pass->set_source_texture(hdr_color_texture);
689 bloom_pass->set_mip_chain_length(5);
690 bloom_pass->set_filter_radius(0.005f);
692 common_final_pass = std::make_unique<render::final_pass>(&window->get_graphics_pipeline(),
nullptr,
resource_manager.get());
693 common_final_pass->set_color_texture(hdr_color_texture);
694 common_final_pass->set_bloom_texture(bloom_pass->get_bloom_texture());
695 common_final_pass->set_bloom_weight(0.04f);
699 resample_pass = std::make_unique<render::resample_pass>(&window->get_graphics_pipeline(),
nullptr,
resource_manager.get());
700 resample_pass->set_source_texture(ldr_color_texture_a);
701 resample_pass->set_enabled(
false);
706 ui_material_pass = std::make_unique<render::material_pass>(&window->get_graphics_pipeline(),
nullptr,
resource_manager.get());
707 ui_material_pass->set_fallback_material(fallback_material);
710 ui_material_pass->set_clear_value({{0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0});
712 ui_compositor = std::make_unique<render::compositor>();
713 ui_compositor->add_pass(ui_material_pass.get());
718 sky_pass = std::make_unique<render::sky_pass>(&window->get_graphics_pipeline(), hdr_framebuffer.get(),
resource_manager.get());
720 sky_pass->set_clear_value({{0.0f, 0.0f, 0.0f, 0.0f}, 0.0f, 0});
723 surface_material_pass = std::make_unique<render::material_pass>(&window->get_graphics_pipeline(), hdr_framebuffer.get(),
resource_manager.get());
724 surface_material_pass->set_fallback_material(fallback_material);
726 surface_compositor = std::make_unique<render::compositor>();
727 surface_compositor->add_pass(sky_pass.get());
728 surface_compositor->add_pass(surface_material_pass.get());
729 surface_compositor->add_pass(bloom_pass.get());
730 surface_compositor->add_pass(common_final_pass.get());
731 surface_compositor->add_pass(resample_pass.get());
741 renderer = std::make_unique<render::renderer>(window->get_graphics_pipeline(), *
resource_manager);
746 void game::setup_scenes()
751 constexpr
float scene_scale = 1.0f / 100.0f;
754 const auto& viewport_size = window->get_viewport_size();
755 const float viewport_aspect_ratio =
static_cast<float>(viewport_size[0]) /
static_cast<float>(viewport_size[1]);
758 surface_scene = std::make_unique<scene::collection>();
759 surface_scene->set_scale(scene_scale);
762 surface_camera = std::make_shared<scene::camera>();
763 surface_camera->set_perspective(math::radians<float>(45.0f), viewport_aspect_ratio, 0.5f);
764 surface_camera->set_compositor(surface_compositor.get());
765 surface_camera->set_composite_index(0);
768 underground_scene = std::make_unique<scene::collection>();
769 underground_scene->set_scale(scene_scale);
772 underground_camera = std::make_shared<scene::camera>();
773 underground_camera->set_perspective(math::radians<float>(45.0f), viewport_aspect_ratio, 0.5f);
776 active_scene =
nullptr;
781 void game::setup_animation()
784 timeline = std::make_unique<::timeline>();
788 animator = std::make_unique<::animator>();
791 void game::setup_ui()
795 debug_font_size_pt = 10.0f;
796 menu_font_size_pt = 22.0f;
797 title_font_size_pt = 80.0f;
798 dyslexia_font =
false;
808 debug_font_material = std::make_shared<render::material>();
809 menu_font_material = std::make_shared<render::material>();
810 title_font_material = std::make_shared<render::material>();
819 catch (
const std::exception& e)
825 const auto& viewport_size = window->get_viewport_size();
826 const float viewport_aspect_ratio =
static_cast<float>(viewport_size[0]) /
static_cast<float>(viewport_size[1]);
829 ui_scene = std::make_unique<scene::collection>();
832 ui_camera = std::make_unique<scene::camera>();
833 ui_camera->set_compositor(ui_compositor.get());
834 const float clip_left = 0.0f;
835 const float clip_right =
static_cast<float>(viewport_size.x());
836 const float clip_top = 0.0f;
837 const float clip_bottom =
static_cast<float>(viewport_size.y());
838 const float clip_near = -100.0f;
839 const float clip_far = 100.0f;
840 ui_camera->set_orthographic(clip_left, clip_right, clip_top, clip_bottom, clip_near, clip_far);
841 ui_camera->look_at({0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 1.0f, 0.0f});
844 menu_bg_material = std::make_shared<render::material>();
846 std::shared_ptr<render::matvar_fvec4> menu_bg_tint = std::make_shared<render::matvar_fvec4>(1,
math::fvec4{0.0f, 0.0f, 0.0f, 0.5f});
847 menu_bg_material->set_variable(
"tint", menu_bg_tint);
851 menu_bg_billboard = std::make_unique<scene::billboard>();
852 menu_bg_billboard->set_material(menu_bg_material);
853 menu_bg_billboard->set_scale({
std::ceil(viewport_size.x() * 0.5f),
std::ceil(viewport_size.y() * 0.5f), 1.0f});
854 menu_bg_billboard->set_translation({
std::floor(viewport_size.x() * 0.5f),
std::floor(viewport_size.y() * 0.5f), -100.0f});
857 fade_transition = std::make_unique<screen_transition>();
859 fade_transition_color = std::make_shared<render::matvar_fvec3>(1,
math::fvec3{0, 0, 0});
860 fade_transition->get_material()->set_variable(
"color", fade_transition_color);
861 fade_transition->get_billboard()->set_translation({0, 0, 98});
864 radial_transition_inner = std::make_unique<screen_transition>();
868 radial_transition_outer = std::make_unique<screen_transition>();
873 auto menu_bg_frame_callback = [menu_bg_tint](
int channel,
const float& opacity)
875 menu_bg_tint->set(
math::fvec4{0.0f, 0.0f, 0.0f, opacity});
879 menu_bg_fade_in_animation = std::make_unique<animation<float>>();
884 channel->
insert_keyframe({config::menu_fade_in_duration, config::menu_bg_opacity});
885 menu_bg_fade_in_animation->set_frame_callback(menu_bg_frame_callback);
886 menu_bg_fade_in_animation->set_start_callback
890 ui_scene->add_object(*menu_bg_billboard);
892 menu_bg_tint->set(
math::fvec4{0.0f, 0.0f, 0.0f, 0.0f});
899 menu_bg_fade_out_animation = std::make_unique<animation<float>>();
905 menu_bg_fade_out_animation->set_frame_callback(menu_bg_frame_callback);
906 menu_bg_fade_out_animation->set_end_callback
910 ui_scene->remove_object(*menu_bg_billboard);
918 ui_scene->add_object(*ui_camera);
919 ui_scene->add_object(*fade_transition->get_billboard());
927 window_resized_subscription = window->get_resized_channel().subscribe
929 [&](
const auto&
event)
931 const auto& viewport_size =
event.window->get_viewport_size();
932 const float viewport_aspect_ratio =
static_cast<float>(viewport_size.x()) /
static_cast<float>(viewport_size.y());
938 surface_camera->set_aspect_ratio(viewport_aspect_ratio);
941 ui_camera->set_orthographic
944 static_cast<float>(viewport_size.x()),
946 static_cast<float>(viewport_size.y()),
947 ui_camera->get_clip_near(),
948 ui_camera->get_clip_far()
952 menu_bg_billboard->set_scale({
std::ceil(viewport_size.x() * 0.5f),
std::ceil(viewport_size.y() * 0.5f), 1.0f});
953 menu_bg_billboard->set_translation({
std::floor(viewport_size.x() * 0.5f),
std::floor(viewport_size.y() * 0.5f), -100.0f});
956 frame_time_text->set_translation({
std::round(0.0f),
std::round(viewport_size.y() - debug_font.get_font_metrics().size), 99.0f});
964 void game::setup_rng()
966 std::random_device rd;
970 void game::setup_entities()
973 entity_registry = std::make_unique<entt::registry>();
976 void game::setup_systems()
978 const auto& viewport_size = window->get_viewport_size();
979 math::fvec4 viewport = {0.0f, 0.0f,
static_cast<float>(viewport_size[0]),
static_cast<float>(viewport_size[1])};
982 terrain_system = std::make_unique<::terrain_system>(*entity_registry);
985 camera_system = std::make_unique<::camera_system>(*entity_registry);
995 behavior_system = std::make_unique<::behavior_system>(*entity_registry);
998 steering_system = std::make_unique<::steering_system>(*entity_registry);
1004 ik_system = std::make_unique<::ik_system>(*entity_registry);
1016 physics_system = std::make_unique<::physics_system>(*entity_registry);
1024 spatial_system = std::make_unique<::spatial_system>(*entity_registry);
1030 orbit_system = std::make_unique<::orbit_system>(*entity_registry);
1045 render_system = std::make_unique<::render_system>(*entity_registry);
1052 void game::setup_controls()
1072 event::dispatcher* input_event_dispatcher = &input_manager->get_event_dispatcher();
1073 window_action_map.set_event_dispatcher(input_event_dispatcher);
1074 menu_action_map.set_event_dispatcher(input_event_dispatcher);
1075 movement_action_map.set_event_dispatcher(input_event_dispatcher);
1076 camera_action_map.set_event_dispatcher(input_event_dispatcher);
1077 ant_action_map.set_event_dispatcher(input_event_dispatcher);
1078 debug_action_map.set_event_dispatcher(input_event_dispatcher);
1081 control_profile_filename =
"controls.cfg";
1106 mouse_pan_factor = mouse_radians_per_pixel * mouse_pan_sensitivity * (mouse_invert_pan ? -1.0 : 1.0);
1107 mouse_tilt_factor = mouse_radians_per_pixel * mouse_tilt_sensitivity * (mouse_invert_tilt ? -1.0 : 1.0);
1110 gamepad_pan_factor = gamepad_radians_per_second * gamepad_pan_sensitivity * (gamepad_invert_pan ? -1.0 : 1.0);
1111 gamepad_tilt_factor = gamepad_radians_per_second * gamepad_tilt_sensitivity * (gamepad_invert_tilt ? -1.0 : 1.0);
1132 void game::setup_debugging()
1134 cli = std::make_unique<debug::cli>();
1136 const auto& viewport_size = window->get_viewport_size();
1138 frame_time_text = std::make_unique<scene::text>();
1139 frame_time_text->set_material(debug_font_material);
1140 frame_time_text->set_color({1.0f, 1.0f, 0.0f, 1.0f});
1141 frame_time_text->set_font(&debug_font);
1142 frame_time_text->set_translation({
std::round(0.0f),
std::round(viewport_size.y() - debug_font.get_font_metrics().size), 99.0f});
1145 ui_scene->add_object(*frame_time_text);
1146 debug_ui_visible =
true;
1150 void game::setup_timing()
1153 max_frame_rate =
static_cast<float>(window_manager->get_display(0).get_refresh_rate() * 2);
1160 const auto fixed_update_interval = std::chrono::duration_cast<::frame_scheduler::duration_type>(std::chrono::duration<double>(1.0 / fixed_update_rate));
1161 const auto min_frame_duration = (limit_frame_rate) ? std::chrono::duration_cast<::frame_scheduler::duration_type>(std::chrono::duration<double>(1.0 / max_frame_rate)) : frame_scheduler::duration_type::zero();
1162 const auto max_frame_duration = fixed_update_interval * 15;
1172 average_frame_duration.reserve(15);
1175 void game::shutdown_audio()
1181 alcMakeContextCurrent(
nullptr);
1182 alcDestroyContext(alc_context);
1187 alcCloseDevice(alc_device);
1195 const float t = std::chrono::duration<float>(fixed_update_time).count();
1196 const float dt = std::chrono::duration<float>(fixed_update_interval).count();
1199 sky_pass->update_tweens();
1202 window_manager->update();
1205 while (!function_queue.empty())
1207 function_queue.front()();
1208 function_queue.pop();
1244 const float alpha =
static_cast<float>(std::chrono::duration<double, ::frame_scheduler::duration_type::period>{accumulated_time} / fixed_update_interval);
1248 const float average_frame_fps = 1000.0f / average_frame_ms;
1251 frame_time_text->set_content(
std::format(
"{:5.02f}ms / {:5.02f} FPS", average_frame_ms, average_frame_fps));
1254 input_manager->update();
1265 window->swap_buffers();
1271 state_machine.emplace(std::make_unique<main_menu_state>(*
this,
true));
void setup_ant_controls(::game &ctx)
void setup_camera_controls(::game &ctx)
Single channel in a keyframe animation.
void insert_keyframe(const keyframe &k)
Adds a keyframe to the animation.
void update(float t, float dt) override
Perform's a system's update() function.
void interpolate(float alpha)
Progresses a set of animations.
void add_animation(animation_base *animation)
Adds an animation to the animator.
void animate(float dt)
Progresses all active animations by dt.
const geom::rectangle< int > & get_usable_bounds() const noexcept
Returns the usable bounds of the display, which excludes areas reserved by the OS for things like men...
static std::unique_ptr< window_manager > instance()
Allocates and returns a window manager.
Calculates apparent properties of celestial bodies as seen by an observer.
virtual void update(float t, float dt)
Adds the timestep dt, scaled by set time scale, to the current time, then calculates apparent propert...
void set_sky_pass(::render::sky_pass *pass)
void set_transmittance_samples(std::size_t samples)
Sets the number of samples to take when integrating atmospheric transmittance.
Updates variables related to atmospheric scattering.
virtual void update(float t, float dt)
Perform's a system's update() function.
void set_sky_pass(::render::sky_pass *pass)
virtual void update(float t, float dt)
Perform's a system's update() function.
Calculates the color and luminance of blackbody radiators.
void update(float t, float dt) override
Perform's a system's update() function.
void interpolate(float alpha)
void set_viewport(const math::fvec4 &viewport)
void update(float t, float dt) override
Perform's a system's update() function.
Maintains a spatially partitioned set of collision meshes.
virtual void update(float t, float dt)
Perform's a system's update() function.
Applies constraint stacks to transform components.
virtual void update(float t, float dt)
Perform's a system's update() function.
Forwards messages from publishers to subscribers.
Schedules fixed- and variable-rate updates.
void set_min_frame_duration(duration_type duration) noexcept
Sets the minimum frame duration.
void set_max_frame_duration(duration_type duration) noexcept
Sets the maximum accumulated frame duration.
void refresh() noexcept
Resets the accumulated time (at) and frame timer, but not the elapsed fixed-rate update time.
void set_fixed_update_interval(duration_type interval) noexcept
Sets the interval (dt) at which fixed-rate updates are scheduled.
void tick()
Performs any scheduled fixed-rate updates followed by a single variable-rate update.
void set_fixed_update_callback(fixed_update_callback_type &&callback) noexcept
Sets the fixed-rate update callback.
duration_type get_frame_duration() const noexcept
Returns the duration of the previous frame.
clock_type::duration duration_type
Duration type matches the clock's duration type.
void set_variable_update_callback(variable_update_callback_type &&callback) noexcept
Sets the variable-rate update callback.
void execute()
Executes the game.
~game()
Boots down the game.
game(int argc, const char *const *argv)
Boots up the game.
Template used to for generating one or more shader variants from a single source.
void update(float t, float dt) override
Perform's a system's update() function.
void update(float t, float dt) override
Perform's a system's update() function.
Updates the Cartesian position and velocity of orbiting bodies given their Keplerian orbital elements...
virtual void update(float t, float dt)
Scales then adds the timestep dt to the current time, then recalculates the positions of orbiting bod...
void set_gravity(const math::fvec3 &gravity) noexcept
Sets the gravity vector.
void interpolate(float alpha)
void update(float t, float dt) override
Perform's a system's update() function.
A material is associated with exactly one shader program and contains a set of material properties wh...
void add_layer(scene::collection *layer)
void set_renderer(::render::renderer *renderer)
virtual void update(float t, float dt)
Perform's a system's update() function.
void update(float t, float dt) override
Perform's a system's update() function.
constexpr void set_physics_system(physics_system *physics_system) noexcept
Manages the loading, caching, and saving of resources.
bool set_write_path(const std::filesystem::path &path)
Sets the path to a directory or archive where files can be written.
bool save(const T &resource, const std::filesystem::path &path) const
Saves a resource to a file.
bool mount(const std::filesystem::path &path)
Adds a directory or archive to the search path.
std::shared_ptr< T > load(const std::filesystem::path &path)
Loads and caches a resource.
virtual void update(float t, float dt)
Perform's a system's update() function.
virtual void update(float t, float dt)
Perform's a system's update() function.
Generates terrain patches and performs terrain patch LOD selection.
Timeline which executes cues (scheduled functions) when advanced over their respective positions in t...
void set_autoremove(bool enabled)
If enabled, cues will be automatically removed from the timeline when they are triggered.
void apply_control_profile(::game &ctx, const ::control_profile &profile)
Applies a control profile to the game context.
void setup_game_controls(::game &ctx)
void reset_control_profile(::control_profile &profile)
Resets a control profile to default settings.
void enable_debug_controls(::game &ctx)
void setup_debug_controls(::game &ctx)
std::unordered_map< Key, std::any > dict
Unordered dictionary type.
void load_fonts(::game &ctx)
log_message< log_message_severity::trace, Args... > log_trace
Formats and logs a trace message.
log_message< log_message_severity::error, Args... > log_error
Formats and logs an error message.
log_message< log_message_severity::info, Args... > log_info
Formats and logs an info message.
Publish-subscribe messaging.
format
Image and vertex formats.
@ color_clear_bit
Indicates the color buffer should be cleared.
@ depth_clear_bit
Indicates the depth buffer should be cleared.
@ stencil_clear_bit
Indicates the stencil buffer should be cleared.
void select_anti_aliasing_method(::game &ctx, render::anti_aliasing_method method)
void create_framebuffers(::game &ctx)
void change_render_resolution(::game &ctx, float scale)
User-defined literals for compile-time string hashing.
std::stack< std::unique_ptr< T > > state_machine
Stack-based hierarchical state machine.
std::unordered_map< hash::fnv1a32_t, std::string > string_map
Maps 32-bit keys to strings.
constexpr vector< T, N > round(const vector< T, N > &x)
Performs a element-wise round operation.
constexpr vector< T, N > floor(const vector< T, N > &x)
Performs a element-wise floor operation.
constexpr vector< T, N > ceil(const vector< T, N > &x)
Performs an element-wise ceil operation.
@ translucent
Material is translucent.
anti_aliasing_method
Anti-aliasing methods.
std::filesystem::path get_local_config_path()
Returns the absolute path to the directory containing user-specific, device-specific application data...
std::filesystem::path get_executable_data_path()
Returns the absolute path to the directory containing application data.
std::filesystem::path get_shared_config_path()
Returns the absolute path to the directory containing user-specific application data that may be shar...
bool read_or_write_setting(::game &ctx, hash::fnv1a32_t key, T &value)
Reads a setting if found, inserts a setting if not found, and overwrites a setting if a type mismatch...
std::string get_string(const ::game &ctx, hash::fnv1a32_t key)
Returns a localized string.
Container for templated easing functions.
void enable_window_controls(::game &ctx)
void setup_window_controls(::game &ctx)