aboutsummaryrefslogtreecommitdiff
path: root/extension/src/MapSingleton.cpp
diff options
context:
space:
mode:
author Hop311 <hop3114@gmail.com>2023-04-07 01:42:53 +0200
committer Hop311 <hop3114@gmail.com>2023-04-07 01:42:53 +0200
commit513a1328edb89ac695c70164158933aee4546cd7 (patch)
tree8d979d4e8c728bb80543aa13e037a328829122fd /extension/src/MapSingleton.cpp
parent14c2358c7837e644349ea37866607fcd1459d2bc (diff)
Province index and colour lookup texture
Diffstat (limited to 'extension/src/MapSingleton.cpp')
-rw-r--r--extension/src/MapSingleton.cpp125
1 files changed, 111 insertions, 14 deletions
diff --git a/extension/src/MapSingleton.cpp b/extension/src/MapSingleton.cpp
index 9d13496..71977da 100644
--- a/extension/src/MapSingleton.cpp
+++ b/extension/src/MapSingleton.cpp
@@ -12,8 +12,11 @@ MapSingleton* MapSingleton::singleton = nullptr;
void MapSingleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_province_identifier_file", "file_path"), &MapSingleton::load_province_identifier_file);
ClassDB::bind_method(D_METHOD("load_province_shape_file", "file_path"), &MapSingleton::load_province_shape_file);
- ClassDB::bind_method(D_METHOD("get_province_shape_image"), &MapSingleton::get_province_shape_image);
- ClassDB::bind_method(D_METHOD("get_province_identifier_from_colour", "colour"), &MapSingleton::get_province_identifier_from_colour);
+ ClassDB::bind_method(D_METHOD("get_province_identifier_from_pixel_coords", "coords"), &MapSingleton::get_province_identifier_from_pixel_coords);
+ ClassDB::bind_method(D_METHOD("get_width"), &MapSingleton::get_width);
+ ClassDB::bind_method(D_METHOD("get_height"), &MapSingleton::get_height);
+ ClassDB::bind_method(D_METHOD("get_province_index_image"), &MapSingleton::get_province_index_image);
+ ClassDB::bind_method(D_METHOD("get_province_colour_image"), &MapSingleton::get_province_colour_image);
}
MapSingleton* MapSingleton::get_singleton() {
@@ -105,20 +108,17 @@ Error MapSingleton::load_province_identifier_file(String const& file_path) {
continue;
}
std::string error_message;
- if (map.add_province(identifier.utf8().get_data(), colour, error_message)) {
- UtilityFunctions::print(error_message.c_str());
- } else {
+ if (!map.add_province(identifier.utf8().get_data(), colour, error_message)) {
UtilityFunctions::push_error(error_message.c_str());
err = FAILED;
}
}
+ map.lock_provinces();
return err;
}
-String MapSingleton::get_province_identifier_from_colour(Province::colour_t colour) {
- const Province* province = map.get_province_by_colour(colour);
- if (province) return province->get_identifier().c_str();
- else return String{};
+static Province::colour_t colour_at(PackedByteArray const& colour_data_array, int32_t idx) {
+ return (colour_data_array[idx * 3] << 16) | (colour_data_array[idx * 3 + 1] << 8) | colour_data_array[idx * 3 + 2];
}
Error MapSingleton::load_province_shape_file(String const& file_path) {
@@ -133,13 +133,13 @@ Error MapSingleton::load_province_shape_file(String const& file_path) {
province_shape_image.unref();
return err;
}
- int32_t width = province_shape_image->get_width();
- int32_t height = province_shape_image->get_height();
+ width = province_shape_image->get_width();
+ height = province_shape_image->get_height();
if (width < 1 || height < 1) {
UtilityFunctions::push_error("Invalid dimensions (", width, "x", height, ") for province shape file: ", file_path);
err = FAILED;
}
- static const Image::Format expected_format = Image::Format::FORMAT_RGB8;
+ static const Image::Format expected_format = Image::FORMAT_RGB8;
Image::Format format = province_shape_image->get_format();
if (format != expected_format) {
UtilityFunctions::push_error("Invalid format (", format, ", should be ", expected_format, ") for province shape file: ", file_path);
@@ -149,9 +149,106 @@ Error MapSingleton::load_province_shape_file(String const& file_path) {
province_shape_image.unref();
return err;
}
+
+ std::vector<bool> province_checklist(map.get_province_count());
+
+ PackedByteArray shape_data_array = province_shape_image->get_data(), index_data_array;
+ index_data_array.resize(width * height * sizeof(Province::index_t));
+ Province::index_t* index_data = reinterpret_cast<Province::index_t*>(index_data_array.ptrw());
+
+ for (int32_t y = 0; y < height; ++y) {
+ for (int32_t x = 0; x < width; ++x) {
+ const int32_t idx = x + y * width;
+ const Province::colour_t colour = colour_at(shape_data_array, idx);
+ if (colour == Province::NULL_COLOUR) {
+ index_data[idx] = Province::NULL_INDEX;
+ continue;
+ }
+ if (x > 0) {
+ const int32_t jdx = idx - 1;
+ if (colour_at(shape_data_array, jdx) == colour) {
+ index_data[idx] = index_data[jdx];
+ continue;
+ }
+ }
+ if (y > 0) {
+ const int32_t jdx = idx - width;
+ if (colour_at(shape_data_array, jdx) == colour) {
+ index_data[idx] = index_data[jdx];
+ continue;
+ }
+ }
+ const Province* province = map.get_province_by_colour(colour);
+ if (province) {
+ Province::index_t index = province->get_index();
+ index_data[idx] = index;
+ province_checklist[index - 1] = true;
+ continue;
+ }
+ UtilityFunctions::push_error("Unrecognised province colour ", Province::colour_to_hex_string(colour).c_str(), " at (", x, ", ", y, ")");
+ err = FAILED;
+ index_data[idx] = Province::NULL_INDEX;
+ }
+ }
+
+ for (size_t idx = 0; idx < province_checklist.size(); ++idx) {
+ if (!province_checklist[idx]) {
+ Province* province = map.get_province_by_index(idx + 1);
+ if (province) UtilityFunctions::push_error("Province missing from shape image: ", province->to_string().c_str());
+ else UtilityFunctions::push_error("Province missing for index: ", idx + 1);
+ err = FAILED;
+ }
+ }
+
+ province_index_image = Image::create_from_data(width, height, false, Image::FORMAT_RG8, index_data_array);
+ if (province_index_image.is_null()) {
+ UtilityFunctions::push_error("Failed to create province ID image");
+ err = FAILED;
+ }
+
+ PackedByteArray colour_data_array;
+ colour_data_array.resize((Province::MAX_INDEX + 1) * 3);
+ for (int64_t idx = 1; idx <= map.get_province_count(); ++idx) {
+ const Province* province = map.get_province_by_index(idx);
+ if (province) {
+ const Province::colour_t colour = province->get_colour();
+ colour_data_array[3 * idx + 0] = (colour >> 16) & 0xFF;
+ colour_data_array[3 * idx + 1] = (colour >> 8) & 0xFF;
+ colour_data_array[3 * idx + 2] = colour & 0xFF;
+ } else UtilityFunctions::push_error("Missing province at index ", idx);
+ }
+ static const int32_t PROVINCE_INDEX_SQRT = 1 << (sizeof(Province::index_t) * 4);
+ province_colour_image = Image::create_from_data(PROVINCE_INDEX_SQRT, PROVINCE_INDEX_SQRT, false, Image::FORMAT_RGB8, colour_data_array);
+ if (province_colour_image.is_null()) {
+ UtilityFunctions::push_error("Failed to create province colour image");
+ err = FAILED;
+ }
+
return err;
}
-Ref<Image> MapSingleton::get_province_shape_image() const {
- return province_shape_image;
+String MapSingleton::get_province_identifier_from_pixel_coords(Vector2i const& coords) {
+ if (province_index_image.is_valid() && 0 <= coords.x && coords.x < width && 0 <= coords.y && coords.y < height) {
+ const PackedByteArray index_data_array = province_index_image->get_data();
+ const Province::index_t* index_data = reinterpret_cast<const Province::index_t*>(index_data_array.ptr());
+ const Province* province = map.get_province_by_colour(index_data[coords.x + coords.y * width]);
+ if (province) return province->get_identifier().c_str();
+ }
+ return String{};
+}
+
+int32_t MapSingleton::get_width() const {
+ return width;
+}
+
+int32_t MapSingleton::get_height() const {
+ return height;
+}
+
+Ref<Image> MapSingleton::get_province_index_image() const {
+ return province_index_image;
+}
+
+Ref<Image> MapSingleton::get_province_colour_image() const {
+ return province_colour_image;
}