aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/openvic-simulation/country/Country.cpp44
-rw-r--r--src/openvic-simulation/country/Country.hpp12
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.cpp7
-rw-r--r--src/openvic-simulation/interface/GFX.cpp42
-rw-r--r--src/openvic-simulation/interface/GFX.hpp31
-rw-r--r--src/openvic-simulation/interface/GUI.cpp4
-rw-r--r--src/openvic-simulation/interface/GUI.hpp6
-rw-r--r--src/openvic-simulation/testing/Requirement.cpp8
-rw-r--r--src/openvic-simulation/testing/Requirement.hpp12
-rw-r--r--src/openvic-simulation/testing/TestScript.cpp2
-rw-r--r--src/openvic-simulation/testing/TestScript.hpp4
-rw-r--r--src/openvic-simulation/testing/test_scripts/A_001_file_tests.cpp3
-rw-r--r--src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp3
-rw-r--r--src/openvic-simulation/testing/test_scripts/A_003_military_unit_tests.cpp3
-rw-r--r--src/openvic-simulation/testing/test_scripts/A_004_networking_tests.cpp3
-rw-r--r--src/openvic-simulation/testing/test_scripts/A_005_nation_tests.cpp3
-rw-r--r--src/openvic-simulation/testing/test_scripts/A_006_politics_tests.cpp3
-rw-r--r--src/openvic-simulation/types/fixed_point/FixedPoint.hpp73
-rw-r--r--src/openvic-simulation/types/fixed_point/FixedPointLUT.hpp25
-rw-r--r--src/openvic-simulation/types/fixed_point/FixedPointLUT_sin.hpp4
-rw-r--r--src/openvic-simulation/types/fixed_point/FixedPointMath.hpp11
-rw-r--r--src/openvic-simulation/types/fixed_point/lut_generator/lut_generator.py4
-rw-r--r--src/openvic-simulation/utility/Getters.hpp2
23 files changed, 188 insertions, 121 deletions
diff --git a/src/openvic-simulation/country/Country.cpp b/src/openvic-simulation/country/Country.cpp
index 463d1bf..2b022b0 100644
--- a/src/openvic-simulation/country/Country.cpp
+++ b/src/openvic-simulation/country/Country.cpp
@@ -24,17 +24,33 @@ CountryParty::CountryParty(
policies { std::move(new_policies) } {}
Country::Country(
- std::string_view new_identifier, colour_t new_colour, GraphicalCultureType const& new_graphical_culture,
- IdentifierRegistry<CountryParty>&& new_parties, unit_names_map_t&& new_unit_names, bool new_dynamic_tag,
- government_colour_map_t&& new_alternative_colours
-) : HasIdentifierAndColour { new_identifier, new_colour, false }, graphical_culture { new_graphical_culture },
- parties { std::move(new_parties) }, unit_names { std::move(new_unit_names) }, dynamic_tag { new_dynamic_tag },
- alternative_colours { std::move(new_alternative_colours) } {}
+ std::string_view new_identifier,
+ colour_t new_colour,
+ GraphicalCultureType const& new_graphical_culture,
+ IdentifierRegistry<CountryParty>&& new_parties,
+ unit_names_map_t&& new_unit_names,
+ bool new_dynamic_tag,
+ government_colour_map_t&& new_alternative_colours,
+ colour_t new_primary_unit_colour,
+ colour_t new_secondary_unit_colour,
+ colour_t new_tertiary_unit_colour
+) : HasIdentifierAndColour {
+ new_identifier, new_colour, false },
+ graphical_culture { new_graphical_culture },
+ parties { std::move(new_parties) },
+ unit_names { std::move(new_unit_names) },
+ dynamic_tag { new_dynamic_tag },
+ alternative_colours { std::move(new_alternative_colours) },
+ primary_unit_colour { new_primary_unit_colour },
+ secondary_unit_colour { new_secondary_unit_colour },
+ tertiary_unit_colour { new_tertiary_unit_colour }
+ {}
bool CountryManager::add_country(
std::string_view identifier, colour_t colour, GraphicalCultureType const* graphical_culture,
IdentifierRegistry<CountryParty>&& parties, Country::unit_names_map_t&& unit_names, bool dynamic_tag,
- Country::government_colour_map_t&& alternative_colours
+ Country::government_colour_map_t&& alternative_colours,
+ colour_t primary_unit_colour, colour_t secondary_unit_colour, colour_t tertiary_unit_colour
) {
if (identifier.empty()) {
Logger::error("Invalid country identifier - empty!");
@@ -53,7 +69,7 @@ bool CountryManager::add_country(
return countries.add_item({
identifier, colour, *graphical_culture, std::move(parties), std::move(unit_names), dynamic_tag,
- std::move(alternative_colours)
+ std::move(alternative_colours), primary_unit_colour, secondary_unit_colour, tertiary_unit_colour
});
}
@@ -101,6 +117,16 @@ bool CountryManager::load_countries(GameManager const& game_manager, Dataloader
return ret;
}
+bool CountryManager::load_country_colours(ast::NodeCPtr root){
+ return countries.expect_item_dictionary([](Country& country, ast::NodeCPtr colour_node) -> bool {
+ return expect_dictionary_keys(
+ "color1", ONE_EXACTLY, expect_colour(assign_variable_callback(country.primary_unit_colour)),
+ "color2", ONE_EXACTLY, expect_colour(assign_variable_callback(country.secondary_unit_colour)),
+ "color3", ONE_EXACTLY, expect_colour(assign_variable_callback(country.tertiary_unit_colour))
+ )(colour_node);
+ })(root);
+}
+
node_callback_t CountryManager::load_country_party(
PoliticsManager const& politics_manager, IdentifierRegistry<CountryParty>& country_parties
) const {
@@ -180,7 +206,7 @@ bool CountryManager::load_country_data_file(
ret &= add_country(
name, colour, graphical_culture, std::move(parties), std::move(unit_names), is_dynamic,
- std::move(alternative_colours)
+ std::move(alternative_colours), colour_t::null(), colour_t::null(), colour_t::null()
);
return ret;
}
diff --git a/src/openvic-simulation/country/Country.hpp b/src/openvic-simulation/country/Country.hpp
index 5f60534..fd6fa7e 100644
--- a/src/openvic-simulation/country/Country.hpp
+++ b/src/openvic-simulation/country/Country.hpp
@@ -63,11 +63,16 @@ namespace OpenVic {
const unit_names_map_t PROPERTY(unit_names);
const bool PROPERTY_CUSTOM_PREFIX(dynamic_tag, is);
const government_colour_map_t PROPERTY(alternative_colours);
+ colour_t PROPERTY(primary_unit_colour);
+ colour_t PROPERTY(secondary_unit_colour);
+ colour_t PROPERTY(tertiary_unit_colour);
+ // Unit colours not const due to being added after construction
Country(
std::string_view new_identifier, colour_t new_colour, GraphicalCultureType const& new_graphical_culture,
IdentifierRegistry<CountryParty>&& new_parties, unit_names_map_t&& new_unit_names, bool new_dynamic_tag,
- government_colour_map_t&& new_alternative_colours
+ government_colour_map_t&& new_alternative_colours,
+ colour_t new_primary_unit_colour, colour_t new_secondary_unit_colour, colour_t new_tertiary_unit_colour
);
public:
@@ -88,9 +93,12 @@ namespace OpenVic {
bool add_country(
std::string_view identifier, colour_t colour, GraphicalCultureType const* graphical_culture,
IdentifierRegistry<CountryParty>&& parties, Country::unit_names_map_t&& unit_names, bool dynamic_tag,
- Country::government_colour_map_t&& alternative_colours
+ Country::government_colour_map_t&& alternative_colours,
+ colour_t primary_unit_colour, colour_t secondary_unit_colour, colour_t tertiary_unit_colour
);
+ bool load_country_colours(ast::NodeCPtr root);
+
bool load_countries(GameManager const& game_manager, Dataloader const& dataloader, ast::NodeCPtr root);
bool load_country_data_file(
GameManager const& game_manager, std::string_view name, bool is_dynamic, ast::NodeCPtr root
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp
index e1bf093..b7ccba3 100644
--- a/src/openvic-simulation/dataloader/Dataloader.cpp
+++ b/src/openvic-simulation/dataloader/Dataloader.cpp
@@ -822,6 +822,7 @@ bool Dataloader::load_defines(GameManager& game_manager) {
static constexpr std::string_view buildings_file = "common/buildings.txt";
static constexpr std::string_view bookmark_file = "common/bookmarks.txt";
static constexpr std::string_view countries_file = "common/countries.txt";
+ static constexpr std::string_view country_colours_file = "common/country_colors.txt";
static constexpr std::string_view culture_file = "common/cultures.txt";
static constexpr std::string_view governments_file = "common/governments.txt";
static constexpr std::string_view graphical_culture_type_file = "common/graphicalculturetype.txt";
@@ -999,6 +1000,12 @@ bool Dataloader::load_defines(GameManager& game_manager) {
Logger::error("Failed to load countries!");
ret = false;
}
+ if (!game_manager.get_country_manager().load_country_colours(
+ parse_defines(lookup_file(country_colours_file)).get_file_node()
+ )) {
+ Logger::error("Failed to load country colours!");
+ ret = false;
+ }
if (!game_manager.get_pop_manager().get_culture_manager().load_culture_file(
game_manager.get_country_manager(), parse_defines(lookup_file(culture_file)).get_file_node()
)) {
diff --git a/src/openvic-simulation/interface/GFX.cpp b/src/openvic-simulation/interface/GFX.cpp
index ff2737c..06d4cd3 100644
--- a/src/openvic-simulation/interface/GFX.cpp
+++ b/src/openvic-simulation/interface/GFX.cpp
@@ -13,11 +13,11 @@ Font::Font(
node_callback_t Sprite::expect_sprites(length_callback_t length_callback, callback_t<std::unique_ptr<Sprite>&&> callback) {
return expect_dictionary_keys_and_length(
length_callback,
- "spriteType", ZERO_OR_MORE, _expect_instance<Sprite, TextureSprite>(callback),
+ "spriteType", ZERO_OR_MORE, _expect_instance<Sprite, IconTextureSprite>(callback),
"progressbartype", ZERO_OR_MORE, _expect_instance<Sprite, ProgressBar>(callback),
"PieChartType", ZERO_OR_MORE, _expect_instance<Sprite, PieChart>(callback),
"LineChartType", ZERO_OR_MORE, _expect_instance<Sprite, LineChart>(callback),
- "textSpriteType", ZERO_OR_MORE, _expect_instance<Sprite, TextureSprite>(callback),
+ "textSpriteType", ZERO_OR_MORE, _expect_instance<Sprite, IconTextureSprite>(callback),
"maskedShieldType", ZERO_OR_MORE, _expect_instance<Sprite, MaskedFlag>(callback),
"tileSpriteType", ZERO_OR_MORE, _expect_instance<Sprite, TileTextureSprite>(callback),
"corneredTileSpriteType", ZERO_OR_MORE, _expect_instance<Sprite, CorneredTileTextureSprite>(callback),
@@ -28,49 +28,51 @@ node_callback_t Sprite::expect_sprites(length_callback_t length_callback, callba
);
}
-TextureSprite::TextureSprite() : texture_file {}, no_of_frames { NO_FRAMES } {}
+TextureSprite::TextureSprite() : texture_file {} {}
bool TextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) {
bool ret = Sprite::_fill_key_map(key_map);
ret &= add_key_map_entries(key_map,
"texturefile", ZERO_OR_ONE, expect_string(assign_variable_callback_string(texture_file)),
- "noOfFrames", ZERO_OR_ONE, expect_uint(assign_variable_callback(no_of_frames)),
"norefcount", ZERO_OR_ONE, success_callback,
- "effectFile", ZERO_OR_ONE, success_callback,
"allwaystransparent", ZERO_OR_ONE, success_callback,
+ "loadType", ZERO_OR_ONE, success_callback
+ );
+ return ret;
+}
+
+IconTextureSprite::IconTextureSprite() : no_of_frames { NO_FRAMES } {}
+
+bool IconTextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) {
+ bool ret = TextureSprite::_fill_key_map(key_map);
+ ret &= add_key_map_entries(key_map,
+ "noOfFrames", ZERO_OR_ONE, expect_uint(assign_variable_callback(no_of_frames)),
+
+ "effectFile", ZERO_OR_ONE, success_callback,
"transparencecheck", ZERO_OR_ONE, success_callback,
- "loadType", ZERO_OR_ONE, success_callback,
"clicksound", ZERO_OR_ONE, success_callback
);
return ret;
}
-TileTextureSprite::TileTextureSprite() : texture_file {}, size {} {}
+TileTextureSprite::TileTextureSprite() : size {} {}
bool TileTextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) {
- bool ret = Sprite::_fill_key_map(key_map);
+ bool ret = TextureSprite::_fill_key_map(key_map);
ret &= add_key_map_entries(key_map,
- "texturefile", ONE_EXACTLY, expect_string(assign_variable_callback_string(texture_file)),
- "size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)),
-
- "norefcount", ZERO_OR_ONE, success_callback,
- "loadType", ZERO_OR_ONE, success_callback
+ "size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size))
);
return ret;
}
-CorneredTileTextureSprite::CorneredTileTextureSprite() : texture_file {}, size {}, border_size {} {}
+CorneredTileTextureSprite::CorneredTileTextureSprite() : size {}, border_size {} {}
bool CorneredTileTextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) {
- bool ret = Sprite::_fill_key_map(key_map);
+ bool ret = TextureSprite::_fill_key_map(key_map);
ret &= add_key_map_entries(key_map,
- "texturefile", ZERO_OR_ONE, expect_string(assign_variable_callback_string(texture_file)),
"size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)),
- "borderSize", ONE_EXACTLY, expect_ivec2(assign_variable_callback(border_size)),
-
- "allwaystransparent", ZERO_OR_ONE, success_callback,
- "loadType", ZERO_OR_ONE, success_callback
+ "borderSize", ONE_EXACTLY, expect_ivec2(assign_variable_callback(border_size))
);
return ret;
}
diff --git a/src/openvic-simulation/interface/GFX.hpp b/src/openvic-simulation/interface/GFX.hpp
index 108ecb6..49691c1 100644
--- a/src/openvic-simulation/interface/GFX.hpp
+++ b/src/openvic-simulation/interface/GFX.hpp
@@ -46,13 +46,8 @@ namespace OpenVic::GFX {
);
};
- class TextureSprite final : public Sprite {
- friend std::unique_ptr<TextureSprite> std::make_unique<TextureSprite>();
-
+ class TextureSprite : public Sprite {
std::string PROPERTY(texture_file);
- frame_t PROPERTY(no_of_frames);
-
- // TODO - effectFile, allwaystransparent
protected:
TextureSprite();
@@ -63,13 +58,30 @@ namespace OpenVic::GFX {
TextureSprite(TextureSprite&&) = default;
virtual ~TextureSprite() = default;
+ OV_DETAIL_GET_BASE_TYPE(TextureSprite)
OV_DETAIL_GET_TYPE
};
- class TileTextureSprite final : public Sprite {
+ class IconTextureSprite final : public TextureSprite {
+ friend std::unique_ptr<IconTextureSprite> std::make_unique<IconTextureSprite>();
+
+ frame_t PROPERTY(no_of_frames);
+
+ protected:
+ IconTextureSprite();
+
+ bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override;
+
+ public:
+ IconTextureSprite(IconTextureSprite&&) = default;
+ virtual ~IconTextureSprite() = default;
+
+ OV_DETAIL_GET_TYPE
+ };
+
+ class TileTextureSprite final : public TextureSprite {
friend std::unique_ptr<TileTextureSprite> std::make_unique<TileTextureSprite>();
- std::string PROPERTY(texture_file);
ivec2_t PROPERTY(size);
protected:
@@ -84,10 +96,9 @@ namespace OpenVic::GFX {
OV_DETAIL_GET_TYPE
};
- class CorneredTileTextureSprite final : public Sprite {
+ class CorneredTileTextureSprite final : public TextureSprite {
friend std::unique_ptr<CorneredTileTextureSprite> std::make_unique<CorneredTileTextureSprite>();
- std::string PROPERTY(texture_file);
ivec2_t PROPERTY(size);
ivec2_t PROPERTY(border_size);
diff --git a/src/openvic-simulation/interface/GUI.cpp b/src/openvic-simulation/interface/GUI.cpp
index 94e1fe3..ae4cf0e 100644
--- a/src/openvic-simulation/interface/GUI.cpp
+++ b/src/openvic-simulation/interface/GUI.cpp
@@ -240,7 +240,7 @@ bool TextEditBox::_fill_key_map(NodeTools::case_insensitive_key_map_t& key_map,
Scrollbar::Scrollbar()
: slider_button_name {}, track_button_name {}, less_button_name{}, more_button_name {}, size {}, border_size {},
- min_value {}, max_value {}, step_size {}, start_value {}, horizontal { false }, use_range_limit { false },
+ min_value {}, max_value {}, step_size {}, start_value {}, horizontal { false }, range_limited { false },
range_limit_min {}, range_limit_max {}, range_limit_min_icon_name {}, range_limit_max_icon_name {} {
scrollbar_elements.reserve(4); /* Space for 4 buttons, might need 2 more for range limit icons. */
}
@@ -262,7 +262,7 @@ bool Scrollbar::_fill_key_map(NodeTools::case_insensitive_key_map_t& key_map, UI
"stepSize", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(step_size)),
"startValue", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(start_value)),
"horizontal", ONE_EXACTLY, expect_int_bool(assign_variable_callback(horizontal)),
- "useRangeLimit", ZERO_OR_ONE, expect_bool(assign_variable_callback(use_range_limit)),
+ "useRangeLimit", ZERO_OR_ONE, expect_bool(assign_variable_callback(range_limited)),
"rangeLimitMin", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(range_limit_min)),
"rangeLimitMax", ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(range_limit_max)),
"rangeLimitMinIcon", ZERO_OR_ONE, expect_string(assign_variable_callback_string(range_limit_min_icon_name)),
diff --git a/src/openvic-simulation/interface/GUI.hpp b/src/openvic-simulation/interface/GUI.hpp
index f044f7d..7551d1a 100644
--- a/src/openvic-simulation/interface/GUI.hpp
+++ b/src/openvic-simulation/interface/GUI.hpp
@@ -296,7 +296,7 @@ namespace OpenVic::GUI {
fixed_point_t PROPERTY(start_value);
bool PROPERTY_CUSTOM_PREFIX(horizontal, is)
- bool PROPERTY(use_range_limit);
+ bool PROPERTY_CUSTOM_PREFIX(range_limited, is);
fixed_point_t PROPERTY(range_limit_min);
fixed_point_t PROPERTY(range_limit_max);
std::string PROPERTY(range_limit_min_icon_name);
@@ -314,8 +314,8 @@ namespace OpenVic::GUI {
Scrollbar(Scrollbar&&) = default;
virtual ~Scrollbar() = default;
- Button const* get_slider_button() const;
- Button const* get_track_button() const;
+ Button const* get_slider_button() const; /* The button you grab and move up and down the scrollbar. */
+ Button const* get_track_button() const; /* The track/background the slider button moves along. */
Button const* get_less_button() const;
Button const* get_more_button() const;
diff --git a/src/openvic-simulation/testing/Requirement.cpp b/src/openvic-simulation/testing/Requirement.cpp
index e7d03e5..eb48f5b 100644
--- a/src/openvic-simulation/testing/Requirement.cpp
+++ b/src/openvic-simulation/testing/Requirement.cpp
@@ -6,3 +6,11 @@ void Requirement::set_pass(bool in_pass) {
pass = in_pass;
set_tested(true); // Ever setting a pass condition implies it has been tested
}
+
+void Requirement::set_target_value(std::string_view new_target_value) {
+ target_value = new_target_value;
+}
+
+void Requirement::set_actual_value(std::string_view new_actual_value) {
+ actual_value = new_actual_value;
+}
diff --git a/src/openvic-simulation/testing/Requirement.hpp b/src/openvic-simulation/testing/Requirement.hpp
index e91fa79..85a1573 100644
--- a/src/openvic-simulation/testing/Requirement.hpp
+++ b/src/openvic-simulation/testing/Requirement.hpp
@@ -7,15 +7,15 @@ namespace OpenVic {
class Requirement {
// Loaded during construction
- std::string PROPERTY_RW(id);
- std::string PROPERTY_RW(text);
- std::string PROPERTY_RW(acceptance_criteria);
+ std::string PROPERTY(id);
+ std::string PROPERTY(text);
+ std::string PROPERTY(acceptance_criteria);
bool PROPERTY(pass);
bool PROPERTY_RW(tested);
// Initialised and used during script execution
- std::string PROPERTY_RW(target_value);
- std::string PROPERTY_RW(actual_value);
+ std::string PROPERTY(target_value);
+ std::string PROPERTY(actual_value);
public:
Requirement(std::string in_id, std::string in_text, std::string in_acceptance_criteria) {
@@ -27,5 +27,7 @@ namespace OpenVic {
}
void set_pass(bool in_pass);
+ void set_target_value(std::string_view new_target_value);
+ void set_actual_value(std::string_view new_actual_value);
};
}
diff --git a/src/openvic-simulation/testing/TestScript.cpp b/src/openvic-simulation/testing/TestScript.cpp
index ab0bfb9..13858fb 100644
--- a/src/openvic-simulation/testing/TestScript.cpp
+++ b/src/openvic-simulation/testing/TestScript.cpp
@@ -2,6 +2,8 @@
using namespace OpenVic;
+TestScript::TestScript(std::string_view new_script_name) : script_name { new_script_name } {}
+
// Getters
std::vector<Requirement*> TestScript::get_requirements() {
return requirements;
diff --git a/src/openvic-simulation/testing/TestScript.hpp b/src/openvic-simulation/testing/TestScript.hpp
index b41246e..fdf23a5 100644
--- a/src/openvic-simulation/testing/TestScript.hpp
+++ b/src/openvic-simulation/testing/TestScript.hpp
@@ -10,9 +10,11 @@ namespace OpenVic {
std::vector<Requirement*> requirements = std::vector<Requirement*>();
GameManager* PROPERTY_RW(game_manager);
- std::string PROPERTY_RW(script_name);
+ std::string PROPERTY(script_name);
public:
+ TestScript(std::string_view new_script_name);
+
// expects an overriden method that performs arbitrary code execution
// so that each script uniquely performs tests
// for both requirement adding to script and to execute code
diff --git a/src/openvic-simulation/testing/test_scripts/A_001_file_tests.cpp b/src/openvic-simulation/testing/test_scripts/A_001_file_tests.cpp
index e24d44c..213da76 100644
--- a/src/openvic-simulation/testing/test_scripts/A_001_file_tests.cpp
+++ b/src/openvic-simulation/testing/test_scripts/A_001_file_tests.cpp
@@ -5,8 +5,7 @@ namespace OpenVic {
class A_001_file_tests : public TestScript {
public:
- A_001_file_tests() {
- set_script_name("A_001_file_tests");
+ A_001_file_tests() : TestScript { "A_001_file_tests" } {
add_requirements();
}
diff --git a/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp b/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp
index 4bff710..e811144 100644
--- a/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp
+++ b/src/openvic-simulation/testing/test_scripts/A_002_economy_tests.cpp
@@ -5,8 +5,7 @@ namespace OpenVic {
class A_002_economy_tests : public TestScript {
public:
- A_002_economy_tests() {
- set_script_name("A_002_economy_tests");
+ A_002_economy_tests() : TestScript { "A_002_economy_tests" } {
add_requirements();
}
diff --git a/src/openvic-simulation/testing/test_scripts/A_003_military_unit_tests.cpp b/src/openvic-simulation/testing/test_scripts/A_003_military_unit_tests.cpp
index cf572d0..b61abb4 100644
--- a/src/openvic-simulation/testing/test_scripts/A_003_military_unit_tests.cpp
+++ b/src/openvic-simulation/testing/test_scripts/A_003_military_unit_tests.cpp
@@ -5,8 +5,7 @@ namespace OpenVic {
class A_003_military_unit_tests : public TestScript {
public:
- A_003_military_unit_tests() {
- set_script_name("A_003_military_unit_tests");
+ A_003_military_unit_tests() : TestScript { "A_003_military_unit_tests" } {
add_requirements();
}
diff --git a/src/openvic-simulation/testing/test_scripts/A_004_networking_tests.cpp b/src/openvic-simulation/testing/test_scripts/A_004_networking_tests.cpp
index 0e05540..984a3c2 100644
--- a/src/openvic-simulation/testing/test_scripts/A_004_networking_tests.cpp
+++ b/src/openvic-simulation/testing/test_scripts/A_004_networking_tests.cpp
@@ -5,8 +5,7 @@ namespace OpenVic {
class A_004_networking_tests : public TestScript {
public:
- A_004_networking_tests() {
- set_script_name("A_004_networking_tests");
+ A_004_networking_tests() : TestScript { "A_004_networking_tests" } {
add_requirements();
}
diff --git a/src/openvic-simulation/testing/test_scripts/A_005_nation_tests.cpp b/src/openvic-simulation/testing/test_scripts/A_005_nation_tests.cpp
index 6f91ac2..bfa8a59 100644
--- a/src/openvic-simulation/testing/test_scripts/A_005_nation_tests.cpp
+++ b/src/openvic-simulation/testing/test_scripts/A_005_nation_tests.cpp
@@ -5,8 +5,7 @@ namespace OpenVic {
class A_005_nation_tests : public TestScript {
public:
- A_005_nation_tests() {
- set_script_name("A_005_nation_tests");
+ A_005_nation_tests() : TestScript { "A_005_nation_tests" } {
add_requirements();
}
diff --git a/src/openvic-simulation/testing/test_scripts/A_006_politics_tests.cpp b/src/openvic-simulation/testing/test_scripts/A_006_politics_tests.cpp
index 091075c..f9e93d9 100644
--- a/src/openvic-simulation/testing/test_scripts/A_006_politics_tests.cpp
+++ b/src/openvic-simulation/testing/test_scripts/A_006_politics_tests.cpp
@@ -5,8 +5,7 @@ namespace OpenVic {
class A_006_politics_tests : public TestScript {
public:
- A_006_politics_tests() {
- set_script_name("A_006_politics_tests");
+ A_006_politics_tests() : TestScript { "A_006_politics_tests" } {
add_requirements();
}
diff --git a/src/openvic-simulation/types/fixed_point/FixedPoint.hpp b/src/openvic-simulation/types/fixed_point/FixedPoint.hpp
index 6a47194..95d2759 100644
--- a/src/openvic-simulation/types/fixed_point/FixedPoint.hpp
+++ b/src/openvic-simulation/types/fixed_point/FixedPoint.hpp
@@ -6,7 +6,7 @@
#include <sstream>
#include <string_view>
-#include "openvic-simulation/types/fixed_point/FixedPointLUT.hpp"
+#include "openvic-simulation/utility/Getters.hpp"
#include "openvic-simulation/utility/Logger.hpp"
#include "openvic-simulation/utility/NumberUtils.hpp"
#include "openvic-simulation/utility/StringUtils.hpp"
@@ -18,14 +18,32 @@ namespace OpenVic {
static constexpr size_t SIZE = 8;
- static constexpr int32_t PRECISION = FPLUT::SIN_LUT_PRECISION;
+ static constexpr int32_t PRECISION = 16;
static constexpr int64_t ONE = 1 << PRECISION;
+ static constexpr int64_t FRAC_MASK = ONE - 1;
+ /* Fixed points represent any base 2 number with 48 bits above the point and 16 bits below it.
+ * - Any number expressible as n / 2^16 where n is an int64_t can be converted to a fixed point exactly.
+ * - If a number cannot be expressed as an integer divided by 2^16, it will be rounded down to the first
+ * representable number below it. For example: 0.01 = 655.36 / 2^16 becomes 0.0099945068359375 = 655 / 2^16.
+ * - While numbers with an integer part greater than 2^32 can be represented, they do not work properly with
+ * multiplication and division which involve an intermediate value that is 2^16 times larger than the result.
+ * For numbers with integer part smaller than 2^32 the top 16 bits prevent this intermediate value from
+ * overflowing. For larger values this will not work and the result will be missing its most significant bits. */
+
+ private:
+ int64_t PROPERTY_RW_CUSTOM_NAME(value, get_raw_value, set_raw_value);
+
+ /* Sin lookup table */
+ #include "openvic-simulation/types/fixed_point/FixedPointLUT_sin.hpp"
+
+ static_assert(SIN_LUT_PRECISION == PRECISION);
+
+ public:
constexpr fixed_point_t() : value { 0 } {}
constexpr fixed_point_t(int64_t new_value) : value { new_value } {}
constexpr fixed_point_t(int32_t new_value) : value { static_cast<int64_t>(new_value) << PRECISION } {}
- // Trivial destructor
constexpr ~fixed_point_t() = default;
static constexpr fixed_point_t max() {
@@ -200,6 +218,23 @@ namespace OpenVic {
return static_cast<int64_t>(178145LL);
}
+ constexpr fixed_point_t sin() const {
+ int64_t num = (*this % pi2() * one_div_pi2()).get_raw_value();
+
+ const bool negative = num < 0;
+ if (negative) {
+ num = -num;
+ }
+
+ const int64_t index = num >> SIN_LUT_SHIFT;
+ const int64_t a = SIN_LUT[index];
+ const int64_t b = SIN_LUT[index + 1];
+
+ const int64_t fraction = (num - (index << SIN_LUT_SHIFT)) << SIN_LUT_COUNT_LOG2;
+ const int64_t result = a + (((b - a) * fraction) >> SIN_LUT_PRECISION);
+ return !negative ? result : -result;
+ }
+
constexpr bool is_negative() const {
return value < 0;
}
@@ -216,23 +251,35 @@ namespace OpenVic {
// Doesn't account for sign, so -n.abc -> 1 - 0.abc
constexpr fixed_point_t get_frac() const {
- return value & (ONE - 1);
+ return value & FRAC_MASK;
}
constexpr bool is_integer() const {
return get_frac() == 0;
}
- constexpr int64_t to_int64_t() const {
- return value >> PRECISION;
+ constexpr fixed_point_t floor() const {
+ return value & ~FRAC_MASK;
}
- constexpr void set_raw_value(int64_t value) {
- this->value = value;
+ constexpr fixed_point_t ceil() const {
+ return floor() + !is_integer();
}
- constexpr int64_t get_raw_value() const {
- return value;
+ /* WARNING: the results of these rounding functions are affected by the accuracy of base 2 fixed point numbers,
+ * for example 1.0 rounded to a multiple of 0.01 is 0.99945068359375 for down and 1.0094451904296875 for up. */
+ constexpr fixed_point_t round_down_to_multiple(fixed_point_t factor) const {
+ const fixed_point_t remainder = *this % factor;
+ return *this - remainder - (remainder < 0 ? factor : _0());
+ }
+
+ constexpr fixed_point_t round_up_to_multiple(fixed_point_t factor) const {
+ const fixed_point_t remainder = *this % factor;
+ return *this - remainder + (remainder > 0 ? factor : _0());
+ }
+
+ constexpr int64_t to_int64_t() const {
+ return value >> PRECISION;
}
constexpr int32_t to_int32_t() const {
@@ -251,13 +298,13 @@ namespace OpenVic {
return value / static_cast<double>(ONE);
}
- constexpr float to_double_rounded() const {
+ constexpr double to_double_rounded() const {
return NumberUtils::round_to_int64((value / static_cast<double>(ONE)) * 100000.0) / 100000.0;
}
static std::ostream& print(std::ostream& stream, fixed_point_t val, size_t decimal_places = 0) {
if (decimal_places > 0) {
- fixed_point_t err = fixed_point_t::_0_50();
+ fixed_point_t err = _0_50();
for (size_t i = decimal_places; i > 0; --i) {
err /= 10;
}
@@ -612,8 +659,6 @@ namespace OpenVic {
}
private:
- int64_t value;
-
static constexpr fixed_point_t parse_integer(char const* str, char const* const end, bool* successful) {
int64_t parsed_value = StringUtils::string_to_int64(str, end, successful, 10);
return parse(parsed_value);
diff --git a/src/openvic-simulation/types/fixed_point/FixedPointLUT.hpp b/src/openvic-simulation/types/fixed_point/FixedPointLUT.hpp
deleted file mode 100644
index a5d585f..0000000
--- a/src/openvic-simulation/types/fixed_point/FixedPointLUT.hpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#pragma once
-
-#include <cstdint>
-
-namespace OpenVic::FPLUT {
-
-#include "openvic-simulation/types/fixed_point/FixedPointLUT_sin.hpp"
-
- constexpr int32_t SHIFT = SIN_LUT_PRECISION - SIN_LUT_COUNT_LOG2;
-
- constexpr int64_t sin(int64_t value) {
- int sign = 1;
- if (value < 0) {
- value = -value;
- sign = -1;
- }
-
- int index = value >> SHIFT;
- int64_t a = SIN_LUT[index];
- int64_t b = SIN_LUT[index + 1];
- int64_t fraction = (value - (index << SHIFT)) << SIN_LUT_COUNT_LOG2;
- int64_t result = a + (((b - a) * fraction) >> SIN_LUT_PRECISION);
- return result * sign;
- }
-}
diff --git a/src/openvic-simulation/types/fixed_point/FixedPointLUT_sin.hpp b/src/openvic-simulation/types/fixed_point/FixedPointLUT_sin.hpp
index 0c75efe..2b935a3 100644
--- a/src/openvic-simulation/types/fixed_point/FixedPointLUT_sin.hpp
+++ b/src/openvic-simulation/types/fixed_point/FixedPointLUT_sin.hpp
@@ -1,9 +1,7 @@
-#pragma once
-
-#include <cstdint>
static constexpr int32_t SIN_LUT_PRECISION = 16;
static constexpr int32_t SIN_LUT_COUNT_LOG2 = 9;
+static constexpr int32_t SIN_LUT_SHIFT = SIN_LUT_PRECISION - SIN_LUT_COUNT_LOG2;
static constexpr int64_t SIN_LUT[(1 << SIN_LUT_COUNT_LOG2) + 1] = {
0, 804, 1608, 2412, 3216, 4019, 4821, 5623, 6424, 7224, 8022, 8820, 9616, 10411, 11204, 11996,
diff --git a/src/openvic-simulation/types/fixed_point/FixedPointMath.hpp b/src/openvic-simulation/types/fixed_point/FixedPointMath.hpp
deleted file mode 100644
index 6cdb926..0000000
--- a/src/openvic-simulation/types/fixed_point/FixedPointMath.hpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#pragma once
-
-#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
-
-namespace OpenVic::FPMath {
- constexpr fixed_point_t sin(fixed_point_t number) {
- number %= fixed_point_t::pi2();
- number *= fixed_point_t::one_div_pi2();
- return FPLUT::sin(number.get_raw_value());
- }
-}
diff --git a/src/openvic-simulation/types/fixed_point/lut_generator/lut_generator.py b/src/openvic-simulation/types/fixed_point/lut_generator/lut_generator.py
index 8ae7a32..e20eaa3 100644
--- a/src/openvic-simulation/types/fixed_point/lut_generator/lut_generator.py
+++ b/src/openvic-simulation/types/fixed_point/lut_generator/lut_generator.py
@@ -20,12 +20,10 @@ def generate_sin_lut(precision : int, count_log2 : int):
SinLut.append(SinLut[0])
output = [
- "#pragma once",
- "",
- "#include <cstdint>",
"",
f"static constexpr int32_t SIN_LUT_PRECISION = {precision};",
f"static constexpr int32_t SIN_LUT_COUNT_LOG2 = {count_log2};",
+ "static constexpr int32_t SIN_LUT_SHIFT = SIN_LUT_PRECISION - SIN_LUT_COUNT_LOG2;",
"",
"static constexpr int64_t SIN_LUT[(1 << SIN_LUT_COUNT_LOG2) + 1] = {"
]
diff --git a/src/openvic-simulation/utility/Getters.hpp b/src/openvic-simulation/utility/Getters.hpp
index fa76e74..0a6917c 100644
--- a/src/openvic-simulation/utility/Getters.hpp
+++ b/src/openvic-simulation/utility/Getters.hpp
@@ -121,7 +121,7 @@ ACCESS:
#define PROPERTY_RW_FULL(NAME, GETTER_NAME, SETTER_NAME, ACCESS) \
PROPERTY_FULL(NAME, GETTER_NAME, ACCESS) \
public: \
- void SETTER_NAME(decltype(NAME) new_##NAME) { \
+ constexpr void SETTER_NAME(decltype(NAME) new_##NAME) { \
NAME = new_##NAME; \
} \
ACCESS: