summaryrefslogtreecommitdiffhomepage
path: root/crop-tool
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-06-08 21:17:51 +0200
committerStanislaw Halik <sthalik@misaki.pl>2022-06-08 21:17:51 +0200
commit9fa9dda6052d584326a68ed69fa8e8619f13b99b (patch)
treeca044644e30d6b9d355f22ecf570020e44b938cf /crop-tool
parent66968b083c8e2ee12819735f9aa9583192dc8091 (diff)
update
Diffstat (limited to 'crop-tool')
-rw-r--r--crop-tool/atlas.cpp2
-rw-r--r--crop-tool/crop-tool.cpp37
-rw-r--r--crop-tool/serialize.cpp103
-rw-r--r--crop-tool/serialize.hpp (renamed from crop-tool/atlas.hpp)17
4 files changed, 139 insertions, 20 deletions
diff --git a/crop-tool/atlas.cpp b/crop-tool/atlas.cpp
deleted file mode 100644
index 0cb6eaf8..00000000
--- a/crop-tool/atlas.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "atlas.hpp"
-#include "../json.hpp"
diff --git a/crop-tool/crop-tool.cpp b/crop-tool/crop-tool.cpp
index 1acbc397..6de44a96 100644
--- a/crop-tool/crop-tool.cpp
+++ b/crop-tool/crop-tool.cpp
@@ -1,5 +1,5 @@
#include "../defs.hpp"
-#include "atlas.hpp"
+#include "serialize.hpp"
#include <Corrade/Utility/Arguments.h>
#include <Corrade/Utility/Debug.h>
#include <Corrade/Utility/DebugStl.h>
@@ -15,6 +15,9 @@
#include <cstring>
#include <cmath>
+#undef MIN
+#undef MAX
+
#ifdef _WIN32
# define EX_OK 0 /* successful termination */
# define EX_USAGE 64 /* command line usage error */
@@ -24,18 +27,20 @@
# include <sysexits.h>
#endif
+#if 0
static std::string fix_path_separators(const std::filesystem::path& path)
{
auto str = path.string();
std::replace(str.begin(), str.end(), '\\', '/');
return str;
}
+#endif
struct file
{
std::filesystem::path name;
cv::Mat4b mat;
- cv::Point2i offset, orig_size;
+ cv::Point2i offset;
};
struct dir
@@ -85,8 +90,6 @@ find_image_bounds(const std::filesystem::path& path, const cv::Mat4b& mat)
static std::optional<file> load_file(const std::filesystem::path& filename)
{
- Debug{} << "load" << fix_path_separators(filename.string());
-
auto mat = progn(
cv::Mat mat_ = cv::imread(filename.string(), cv::IMREAD_UNCHANGED);
if (mat_.empty() || mat_.type() != CV_8UC4)
@@ -135,7 +138,7 @@ static std::optional<file> load_file(const std::filesystem::path& filename)
cv::Mat4b resized{size};
cv::resize(mat({start, size}), resized, dest_size, 0, 0, cv::INTER_LANCZOS4);
- file ret {filename, resized.clone(), start, size};
+ file ret { filename, resized.clone(), offset };
return std::make_optional(std::move(ret));
}
@@ -147,8 +150,6 @@ static std::optional<dir> load_directory(const std::filesystem::path& dirname)
return std::nullopt;
}
- Debug{} << "loading" << dirname.string();
-
dir ret;
for (int i = 1; i <= 9999; i++)
{
@@ -184,15 +185,21 @@ int main(int argc, char** argv)
if (auto* c = strrchr(argv[0], '/'); c && c[1])
args.setCommand(c+1);
#endif
- args.addOption('o', "output", "output")
- .addArrayArgument("directories")
+ args.addOption('o', "output", "./output")
+ .addArgument("directory")
.addOption('W', "width", "")
.addOption('H', "height", "")
.addOption('x', "offset")
.setHelp("offset", {}, "WxH");
args.parse(argc, argv);
- auto output = args.value<std::string>("output");
+ std::filesystem::path output = args.value<std::string>("output");
+ std::filesystem::path pathname = args.value<std::string>("directory");
std::vector<dir> dirs;
+ auto anim_info = anim::from_json(pathname / "atlas.json");
+
+ if (!anim_info)
+ goto usage;
+
if (unsigned w = args.value<unsigned>("width"); w != 0)
options.width = w;
if (unsigned h = args.value<unsigned>("height"); h != 0)
@@ -220,12 +227,14 @@ int main(int argc, char** argv)
options.offset = {x, y};
}
- for (std::size_t i = 0, cnt = args.arrayValueCount("directories"); i < cnt; i++)
+ using anim_dir_t = std::underlying_type_t<anim_direction>;
+ for (auto i = (anim_dir_t)anim_direction::MIN; i < (anim_dir_t)anim_direction::MAX; i++)
{
- auto dir = load_directory(args.arrayValue("directories", i));
- if (!dir)
+ auto name = anim_direction_group::anim_direction_string((anim_direction)i);
+ auto result = load_directory(pathname / name);
+ if (!result)
goto usage;
- dirs.push_back(std::move(*dir));
+ dirs.push_back(std::move(*result));
}
return 0;
diff --git a/crop-tool/serialize.cpp b/crop-tool/serialize.cpp
new file mode 100644
index 00000000..8d3a5cf7
--- /dev/null
+++ b/crop-tool/serialize.cpp
@@ -0,0 +1,103 @@
+#include "serialize.hpp"
+#include "../json.hpp"
+
+#include <algorithm>
+#include <utility>
+#include <fstream>
+#include <Corrade/Utility/Debug.h>
+#include <Corrade/Utility/DebugStl.h>
+
+using Corrade::Utility::Debug;
+using Corrade::Utility::Error;
+
+static constexpr
+std::pair<anim_direction, const char*> anim_direction_map[] = {
+ { anim_direction::Invalid, "x" },
+ { anim_direction::N, "N" },
+ { anim_direction::NE, "NE" },
+ { anim_direction::E, "E" },
+ { anim_direction::SE, "SE" },
+ { anim_direction::S, "S" },
+ { anim_direction::SW, "SW" },
+ { anim_direction::W, "W" },
+ { anim_direction::NW, "NW" },
+};
+
+namespace nlohmann {
+
+template<>
+struct adl_serializer<Magnum::Vector2i> final {
+ static void to_json(json& j, const Magnum::Vector2i& x)
+ {
+ j["x"] = x[0];
+ j["y"] = x[1];
+ }
+
+ static void from_json(const json& j, Magnum::Vector2i& x)
+ {
+ j.at("x").get_to(x[0]);
+ j.at("y").get_to(x[1]);
+ }
+};
+
+template<>
+struct adl_serializer<anim_direction> final {
+ static void to_json(json& j, anim_direction x)
+ {
+ auto it = std::find_if(std::cbegin(anim_direction_map), std::cend(anim_direction_map),
+ [=](const auto& pair) { return x == pair.first; });
+ if (it != std::cend(anim_direction_map))
+ j = it->second;
+ else
+ j = anim_direction_map[0].second;
+ }
+ static void from_json(const json& j, anim_direction& x)
+ {
+ std::string str = j;
+ auto it = std::find_if(std::cbegin(anim_direction_map), std::cend(anim_direction_map),
+ [&](const auto& pair) { return str == pair.second; });
+ if (it != std::cend(anim_direction_map))
+ x = it->first;
+ else
+ x = anim_direction::Invalid;
+ }
+};
+
+} // namespace nlohmann
+
+NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(anim_frame, ground);
+NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(anim_direction_group, group, frames);
+NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(anim, name, nframes, actionframe, fps, directions);
+
+std::optional<anim> anim::from_json(const std::filesystem::path& pathname)
+{
+ using namespace nlohmann;
+ std::ifstream s;
+ s.exceptions(s.exceptions() | std::ios::failbit);
+ try {
+ s.open(pathname, std::ios_base::in);
+ } catch (const std::ios_base::failure& e) {
+ Error{} << "failed to open" << pathname << ":" << e.what();
+ return std::nullopt;
+ }
+ anim ret;
+ try {
+ json j;
+ s >> j;
+ using nlohmann::from_json;
+ from_json(j, ret);
+ } catch (const std::exception& e) {
+ Error{} << "failed to parse" << pathname.string() << ":" << e.what();
+ }
+ return std::make_optional(std::move(ret));
+}
+
+const char* anim_direction_group::anim_direction_string(anim_direction group)
+{
+ auto it = std::find_if(std::cbegin(anim_direction_map), std::cend(anim_direction_map),
+ [=](const auto& pair) { return group == pair.first; });
+ if (it != std::cend(anim_direction_map))
+ return it->second;
+ else
+ return "(unknown)";
+}
diff --git a/crop-tool/atlas.hpp b/crop-tool/serialize.hpp
index ad74fe4d..e93cf6f4 100644
--- a/crop-tool/atlas.hpp
+++ b/crop-tool/serialize.hpp
@@ -1,12 +1,15 @@
#pragma once
+
+#include <string>
#include <array>
#include <vector>
+#include <optional>
+#include <filesystem>
#include <Magnum/Trade/ImageData.h>
struct anim_frame
{
- Magnum::Trade::ImageData2D image;
- Magnum::Vector2us ground_offset = {};
+ Magnum::Vector2i ground = {};
};
enum class anim_direction : unsigned char
@@ -18,14 +21,20 @@ enum class anim_direction : unsigned char
struct anim_direction_group
{
+ static const char* anim_direction_string(anim_direction group);
+ anim_direction group;
std::vector<anim_frame> frames;
- anim_direction dir = anim_direction::Invalid;
+
+ Magnum::Vector2i ground = {};
};
struct anim
{
+ std::string name;
std::array<anim_direction_group, (unsigned)anim_direction::MAX> directions;
- int num_frames = 0, action_frame = 0, fps = default_fps;
+ int nframes = 0, actionframe = 0, fps = default_fps;
+
+ static std::optional<anim> from_json(const std::filesystem::path& pathname);
static constexpr int default_fps = 24;
};