-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Better portal vis culling - add game settings module #35
- fix various culling related issues - the exit portal is now doing proper area visibility checks resulting in less drawing - area visible through the exit portal is now culled by default if the entry portal is not visible -> can be tweaked via game_settings.toml - add game_settings module using file `portal2-rtx/game_settings.toml` (auto generates but accepts valid tweaks to settings
- Loading branch information
Showing
17 changed files
with
996 additions
and
324 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#include "std_include.hpp" | ||
|
||
namespace components | ||
{ | ||
void game_settings::write_toml() | ||
{ | ||
std::ofstream file; | ||
file.open((game::root_path + "portal2-rtx\\game_settings.toml").c_str()); | ||
|
||
file << "# This file is autogenerated. Valid modifications of settings are considered and will be written back to the file." << std::endl << std::endl; | ||
|
||
const std::uint32_t setting_count = sizeof(var_definitions) / sizeof(variable); | ||
for (auto s = 0u; s < setting_count; s++) | ||
{ | ||
auto var = reinterpret_cast<variable*>(reinterpret_cast<char*>(&vars) + s * sizeof(variable)); | ||
|
||
file << "# " << var->m_desc << std::endl; | ||
file << "# Type: " << var->get_str_type() << " || Default: " << var->get_str_value(true) << std::endl; | ||
file << var->m_name << " = " << var->get_str_value() << std::endl << std::endl; | ||
} | ||
|
||
file.close(); | ||
} | ||
|
||
bool game_settings::parse_toml() | ||
{ | ||
std::ifstream file; | ||
if (utils::open_file_homepath("portal2-rtx\\", "game_settings.toml", file)) | ||
{ | ||
// file exists | ||
file.close(); | ||
|
||
try | ||
{ | ||
auto config = toml::parse("portal2-rtx\\game_settings.toml"); | ||
|
||
// # | ||
auto to_float = [](const toml::value& entry, float default_setting = 0.0f) | ||
{ | ||
if (entry.is_floating()) { | ||
return static_cast<float>(entry.as_floating()); | ||
} | ||
|
||
if (entry.is_integer()) { | ||
return static_cast<float>(entry.as_integer()); | ||
} | ||
|
||
try { // this will fail and let the user know whats wrong | ||
return static_cast<float>(entry.as_floating()); | ||
} | ||
catch (toml::type_error& err) { | ||
game::console(); printf("%s\n", err.what()); | ||
} | ||
|
||
return default_setting; | ||
}; | ||
|
||
// # | ||
auto to_int = [](const toml::value& entry, int default_setting = 0) | ||
{ | ||
if (entry.is_floating()) { | ||
return static_cast<int>(entry.as_floating()); | ||
} | ||
|
||
if (entry.is_integer()) { | ||
return static_cast<int>(entry.as_integer()); | ||
} | ||
|
||
try { // this will fail and let the user know whats wrong | ||
return static_cast<int>(entry.as_integer()); | ||
} | ||
catch (toml::type_error& err) { | ||
game::console(); printf("%s\n", err.what()); | ||
} | ||
|
||
return default_setting; | ||
}; | ||
|
||
// --------------------------------------- | ||
|
||
#define ASSIGN(name) \ | ||
if (config.contains((#name))) { \ | ||
switch (vars.##name.get_type()) { \ | ||
case (var_type_integer): \ | ||
vars.##name.set_var(to_int(config.at(#name), vars.##name.get_as<int>()), true); break; \ | ||
case (var_type_value): \ | ||
vars.##name.set_var(to_float(config.at(#name), vars.##name.get_as<float>()), true); break; \ | ||
} \ | ||
} | ||
|
||
ASSIGN(portal_visibility_culling); | ||
ASSIGN(check_nodes_for_potential_lights); | ||
|
||
#undef ASSIGN | ||
} | ||
|
||
catch (const toml::syntax_error& err) | ||
{ | ||
game::console(); | ||
printf("%s\n", err.what()); | ||
printf("[GameSettings] Not writing defaults! Please check 'game_settings.toml' or remove the file to re-generate it on next startup!\n"); | ||
return false; | ||
} | ||
} | ||
|
||
// always re-write file | ||
write_toml(); | ||
|
||
return true; | ||
} | ||
|
||
ConCommand xo_gamesettings_update {}; | ||
void xo_gamesettings_update_fn() | ||
{ | ||
game_settings::parse_toml(); | ||
} | ||
|
||
game_settings::game_settings() | ||
{ | ||
parse_toml(); | ||
|
||
// ---- | ||
game::con_add_command(&xo_gamesettings_update, "xo_gamesettings_update", xo_gamesettings_update_fn, "Reloads the game_settings.toml file"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
#pragma once | ||
|
||
namespace components | ||
{ | ||
class game_settings : public component | ||
{ | ||
public: | ||
game_settings(); | ||
~game_settings() = default; | ||
|
||
static inline game_settings* p_this = nullptr; | ||
static auto get() { return &vars; } | ||
|
||
static void write_toml(); | ||
static bool parse_toml(); | ||
|
||
private: | ||
union var_value | ||
{ | ||
int integer; | ||
float value; | ||
}; | ||
|
||
enum var_type : std::uint8_t | ||
{ | ||
var_type_integer = 0, | ||
var_type_value = 1, | ||
}; | ||
|
||
class variable | ||
{ | ||
public: | ||
variable(const char* name, const char* desc, const int integer) : | ||
m_name(name), m_desc(desc), m_type(var_type_integer) | ||
{ | ||
m_var.integer = integer; | ||
m_var_default.integer = integer; | ||
} | ||
|
||
variable(const char* name, const char* desc, const float value) : | ||
m_name(name), m_desc(desc), m_type(var_type_value) | ||
{ | ||
m_var.value = value; | ||
m_var_default.value = value; | ||
} | ||
|
||
const char* get_str_value(bool get_default = false) const | ||
{ | ||
switch (m_type) | ||
{ | ||
case var_type_integer: | ||
return utils::va("%d", !get_default ? m_var.integer : m_var_default.integer); | ||
|
||
case var_type_value: | ||
return utils::va("%.2f", !get_default ? m_var.value : m_var_default.value); | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
const char* get_str_type() const | ||
{ | ||
switch (m_type) | ||
{ | ||
case var_type_integer: | ||
return "INT"; | ||
|
||
case var_type_value: | ||
return "FLOAT"; | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
template <typename T> | ||
T get_as(bool default_val = false) | ||
{ | ||
if (m_type == var_type_integer) { | ||
return static_cast<T>(!default_val ? m_var.integer : m_var_default.integer); | ||
} | ||
|
||
if (m_type == var_type_value) { | ||
return static_cast<T>(!default_val ? m_var.value : m_var_default.value); | ||
} | ||
|
||
throw std::runtime_error("Unknown var_type"); | ||
} | ||
|
||
var_type get_type() const { | ||
return m_type; | ||
} | ||
|
||
// sets var and writes toml | ||
void set_var(const int integer, bool no_toml_update = false) | ||
{ | ||
m_var.integer = integer; | ||
if (!no_toml_update) { | ||
write_toml(); | ||
} | ||
} | ||
|
||
// sets var and writes toml | ||
void set_var(const float value, bool no_toml_update = false) | ||
{ | ||
m_var.value = value; | ||
if (!no_toml_update) { | ||
write_toml(); | ||
} | ||
} | ||
|
||
const char* m_name; | ||
const char* m_desc; | ||
|
||
private: | ||
var_value m_var; | ||
var_value m_var_default; | ||
var_type m_type; | ||
}; | ||
|
||
|
||
struct var_definitions | ||
{ | ||
variable portal_visibility_culling = | ||
{ | ||
"portal_visibility_culling", | ||
"Enable culling of exit portal areas when the entry portal is not visible from the players POV (++ performance)", | ||
1 | ||
}; | ||
|
||
variable check_nodes_for_potential_lights = | ||
{ | ||
"check_nodes_for_potential_lights", | ||
"Check each node for potential emissive light strips (rectangular with limited depth) & force-draw node on match.", | ||
1 | ||
}; | ||
}; //STATIC_ASSERT_SIZE(var_definitions, 2 * sizeof(variable)); | ||
|
||
static inline var_definitions vars = {}; | ||
}; | ||
} |
Oops, something went wrong.