summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt8
-rw-r--r--anim-crop-tool/CMakeLists.txt5
-rw-r--r--anim-crop-tool/atlas.cpp4
-rw-r--r--anim-crop-tool/atlas.hpp8
-rw-r--r--anim-crop-tool/main.cpp35
-rw-r--r--anim/CMakeLists.txt12
-rw-r--r--serialize/CMakeLists.txt5
-rw-r--r--serialize/anim.cpp (renamed from anim/serialize.cpp)12
-rw-r--r--serialize/anim.hpp (renamed from anim/serialize.hpp)8
-rw-r--r--serialize/helper.hpp (renamed from json-magnum.hpp)50
-rw-r--r--serialize/vector.hpp41
11 files changed, 108 insertions, 80 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 41ac4b9a..5e5ef563 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -60,10 +60,10 @@ if(NOT BOOTSTRAP_DEPENDS)
include_directories(.)
add_subdirectory(anim-crop-tool)
- add_subdirectory(anim)
+ add_subdirectory(serialize)
corrade_add_resource(game_RESOURCES resources.conf)
- file(GLOB sources "*.cpp" "shaders/*.cpp" CONFIGURE_ARGS)
+ file(GLOB sources "*.cpp" "shaders/*.cpp" "serialize/*.cpp" CONFIGURE_ARGS)
add_executable(${PROJECT_NAME} WIN32 "${sources}" "${game_RESOURCES}")
target_link_libraries(${PROJECT_NAME} PRIVATE
@@ -72,7 +72,9 @@ if(NOT BOOTSTRAP_DEPENDS)
Magnum::Magnum
Magnum::Shaders
Magnum::Trade
- MagnumIntegration::Glm)
+ MagnumIntegration::Glm
+ nlohmann_json::nlohmann_json
+ )
target_include_directories(${PROJECT_NAME} PRIVATE ${GLM_INCLUDE_DIRS})
target_include_directories(${PROJECT_NAME} PRIVATE magnum-integration/src)
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin)
diff --git a/anim-crop-tool/CMakeLists.txt b/anim-crop-tool/CMakeLists.txt
index 7b6d22a8..76304068 100644
--- a/anim-crop-tool/CMakeLists.txt
+++ b/anim-crop-tool/CMakeLists.txt
@@ -2,8 +2,9 @@ find_package(OpenCV QUIET REQUIRED COMPONENTS core imgcodecs imgproc)
set(self "${PROJECT_NAME}-anim-crop-tool")
include_directories(SYSTEM PRIVATE ${OpenCV_INCLUDE_DIRS})
-link_libraries(Corrade::Utility)
-link_libraries(${PROJECT_NAME}-anim)
+link_libraries(Corrade::Utility Magnum::Magnum)
+link_libraries("${PROJECT_NAME}-serialize")
+link_libraries(opencv_imgproc opencv_imgcodecs opencv_core)
file(GLOB sources "*.cpp" CONFIGURE_ARGS)
add_executable(${self} ${sources})
diff --git a/anim-crop-tool/atlas.cpp b/anim-crop-tool/atlas.cpp
index 8c43d64f..4b005d60 100644
--- a/anim-crop-tool/atlas.cpp
+++ b/anim-crop-tool/atlas.cpp
@@ -1,10 +1,12 @@
#include "atlas.hpp"
-#include "anim/serialize.hpp"
+#include "serialize/anim.hpp"
#include "compat/assert.hpp"
#include <filesystem>
#include <opencv2/imgcodecs.hpp>
+using namespace Magnum::Examples::Serialize;
+
void anim_atlas_row::add_entry(const anim_atlas_entry& x)
{
auto& frame = *x.frame;
diff --git a/anim-crop-tool/atlas.hpp b/anim-crop-tool/atlas.hpp
index 66bddb5d..be74b40a 100644
--- a/anim-crop-tool/atlas.hpp
+++ b/anim-crop-tool/atlas.hpp
@@ -5,10 +5,12 @@
#include <Magnum/Math/Vector2.h>
#include <opencv2/core/mat.hpp>
-struct anim_frame;
-
namespace std::filesystem { class path; }
+namespace Magnum::Examples::Serialize {
+
+struct anim_frame;
+
struct anim_atlas_entry
{
anim_frame* frame;
@@ -35,3 +37,5 @@ public:
Magnum::Vector2i size() const noexcept;
[[nodiscard]] bool dump(const std::filesystem::path& filename) const;
};
+
+} // namespace Magnum::Examples::Serialize
diff --git a/anim-crop-tool/main.cpp b/anim-crop-tool/main.cpp
index 600688c1..be3f7469 100644
--- a/anim-crop-tool/main.cpp
+++ b/anim-crop-tool/main.cpp
@@ -1,9 +1,10 @@
#include "atlas.hpp"
-#include "anim/serialize.hpp"
+#include "serialize/anim.hpp"
#include "compat/defs.hpp"
#include "compat/sysexits.hpp"
#include "compat/assert.hpp"
+#include <cerrno>
#include <cmath>
#include <cstring>
@@ -26,6 +27,8 @@ using Corrade::Utility::Debug;
using std::filesystem::path;
+using namespace Magnum::Examples::Serialize;
+
struct options
{
double scale = 0;
@@ -65,7 +68,7 @@ static bool load_file(anim_group& group, options& opts, anim_atlas& atlas, const
cv::Mat mat = cv::imread(filename.string(), cv::IMREAD_UNCHANGED);
if (mat.empty() || mat.type() != CV_8UC4)
{
- Error{} << "failed to load" << filename << "as RGBA32 image";
+ Error{} << "error: failed to load" << filename << "as RGBA32 image";
return cv::Mat4b{};
}
return cv::Mat4b(std::move(mat));
@@ -78,7 +81,7 @@ static bool load_file(anim_group& group, options& opts, anim_atlas& atlas, const
if (!bounds_ok)
{
- Error{} << "no valid image data in" << filename;
+ Error{} << "error: no valid image data in" << filename;
return false;
}
@@ -101,7 +104,7 @@ static bool load_file(anim_group& group, options& opts, anim_atlas& atlas, const
if (size.width < dest_size.width || size.height < dest_size.height)
{
- Error{} << "refusing to upscale image" << filename;
+ Error{} << "error: refusing to upscale image" << filename;
return false;
}
@@ -125,7 +128,7 @@ static bool load_directory(anim_group& group, options& opts, anim_atlas& atlas)
if (std::error_code ec; !std::filesystem::exists(input_dir/".", ec))
{
- Error{Error::Flag::NoSpace} << "can't open directory " << input_dir << ": " << ec.message();
+ Error{} << "error: can't open directory" << input_dir << ":" << ec.message();
return false;
}
@@ -148,9 +151,8 @@ static bool load_directory(anim_group& group, options& opts, anim_atlas& atlas)
opts.nframes = max-1;
else if (opts.nframes != max-1)
{
- Error{Error::Flag::NoSpace} << "wrong frame count for direction '"
- << group.name << "' -- " << max-1
- << " should be " << opts.nframes;
+ Error{} << "error: wrong frame count for direction" << group.name << ":"
+ << max-1 << "should be" << opts.nframes;
return false;
}
@@ -203,6 +205,7 @@ static std::tuple<options, Arguments, bool> parse_cmdline(int argc, const char*
opts.width = w;
if (int h = args.value<int>("height"); h != 0)
opts.height = h;
+ opts.output_dir = args.value<std::string>("output");
opts.input_file = args.value<std::string>("input");
opts.input_dir = opts.input_file.parent_path();
@@ -248,7 +251,7 @@ int main(int argc, char** argv)
if (!check_atlas_name(anim_info.name))
{
- Error{Error::Flag::NoSpace} << "atlas name '" << anim_info.name << "' contains invalid characters";
+ Error{} << "error: atlas name" << anim_info.name << "contains invalid characters";
return EX_DATAERR;
}
@@ -260,7 +263,7 @@ int main(int argc, char** argv)
if (!(opts.width ^ opts.height) || opts.width < 0 || opts.height < 0)
{
- Error{} << "exactly one of --width, --height must be specified";
+ Error{} << "error: exactly one of --width, --height must be specified";
return usage(args);
}
@@ -270,8 +273,18 @@ int main(int argc, char** argv)
if (!load_directory(group, opts, atlas))
return EX_DATAERR;
- if (!atlas.dump(opts.output_dir/(anim_info.name + ".png")))
+ if (std::error_code ec{}; !std::filesystem::exists(opts.output_dir/".", ec) &&
+ !std::filesystem::create_directory(opts.output_dir, ec)) {
+ Error{} << "error: failed to create output directory"
+ << opts.output_dir << ":" << ec.message();
return EX_CANTCREAT;
+ }
+
+ if (auto pathname = opts.output_dir/(anim_info.name + ".png"); !atlas.dump(pathname)) {
+ Error{} << "error: failed writing image to" << pathname << ":"
+ << std::strerror(errno); // NOLINT(concurrency-mt-unsafe)
+ return EX_CANTCREAT;
+ }
if (!anim_info.to_json(opts.output_dir/(anim_info.name + ".json")))
return EX_CANTCREAT;
diff --git a/anim/CMakeLists.txt b/anim/CMakeLists.txt
deleted file mode 100644
index bc148a06..00000000
--- a/anim/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-find_package(OpenCV QUIET REQUIRED COMPONENTS core imgcodecs imgproc)
-find_package(nlohmann_json QUIET REQUIRED)
-
-set(self "${PROJECT_NAME}-anim")
-
-include_directories(SYSTEM PRIVATE ${OpenCV_INCLUDE_DIRS})
-link_libraries(opencv_imgproc opencv_imgcodecs opencv_core)
-link_libraries(Magnum::Magnum nlohmann_json::nlohmann_json)
-
-file(GLOB sources "*.cpp" CONFIGURE_ARGS)
-add_library(${self} STATIC ${sources})
-
diff --git a/serialize/CMakeLists.txt b/serialize/CMakeLists.txt
new file mode 100644
index 00000000..e695aff2
--- /dev/null
+++ b/serialize/CMakeLists.txt
@@ -0,0 +1,5 @@
+find_package(nlohmann_json QUIET REQUIRED)
+set(self "${PROJECT_NAME}-serialize")
+link_libraries(Magnum::Magnum nlohmann_json::nlohmann_json)
+file(GLOB sources "*.cpp" CONFIGURE_ARGS)
+add_library(${self} STATIC ${sources})
diff --git a/anim/serialize.cpp b/serialize/anim.cpp
index 8c027d9c..c65c24a6 100644
--- a/anim/serialize.cpp
+++ b/serialize/anim.cpp
@@ -1,11 +1,13 @@
-#include "serialize.hpp"
+#include "serialize/vector.hpp"
+#include "serialize/helper.hpp"
+#include "serialize/anim.hpp"
+#include <tuple>
+#include <filesystem>
#include <Corrade/Utility/Debug.h>
#include <Corrade/Utility/DebugStl.h>
-#include "json-magnum.hpp"
-
-using Corrade::Utility::Error;
+namespace Magnum::Examples::Serialize {
#if defined __clang__ || defined __CLION_IDE__
# pragma clang diagnostic push
@@ -30,3 +32,5 @@ bool anim::to_json(const std::filesystem::path& pathname) const noexcept
{
return json_helper<anim>::to_json(*this, pathname);
}
+
+} // namespace Magnum::Examples::Serialize
diff --git a/anim/serialize.hpp b/serialize/anim.hpp
index 3e039a96..f03e3c8c 100644
--- a/anim/serialize.hpp
+++ b/serialize/anim.hpp
@@ -1,14 +1,17 @@
#pragma once
-#include <string>
+#include <tuple>
#include <array>
#include <vector>
+#include <string>
#include <Magnum/Magnum.h>
#include <Magnum/Math/Vector2.h>
namespace std::filesystem { class path; }
+namespace Magnum::Examples::Serialize {
+
struct anim_frame final
{
Magnum::Vector2i ground, offset, size;
@@ -39,3 +42,6 @@ struct anim final
int width = 0, height = 0;
int actionframe = -1, fps = default_fps;
};
+
+} // namespace Magnum::Examples::Serialize
+
diff --git a/json-magnum.hpp b/serialize/helper.hpp
index bcd17e0a..f16ed60c 100644
--- a/json-magnum.hpp
+++ b/serialize/helper.hpp
@@ -1,48 +1,10 @@
#pragma once
-
-#include <cstdio>
-#include <string>
-#include <utility>
+#include <tuple>
#include <fstream>
#include <exception>
+#include <filesystem>
#include <nlohmann/json.hpp>
-#include <Corrade/Utility/Debug.h>
#include <Corrade/Utility/DebugStl.h>
-#include <Magnum/Magnum.h>
-#include <Magnum/Math/Vector2.h>
-
-namespace nlohmann {
-
-template<>
-struct adl_serializer<Magnum::Vector2i> final {
- static void to_json(json& j, const Magnum::Vector2i& x);
- static void from_json(const json& j, Magnum::Vector2i& x);
-};
-
-void adl_serializer<Magnum::Vector2i>::to_json(json& j, const Magnum::Vector2i& val)
-{
- char buf[64];
- snprintf(buf, sizeof(buf), "%d x %d", val[0], val[1]);
- j = buf;
-}
-
-void adl_serializer<Magnum::Vector2i>::from_json(const json& j, Magnum::Vector2i& val)
-{
- std::string str = j;
- int x = 0, y = 0, n = 0;
- int ret = std::sscanf(str.c_str(), "%d x %d%n", &x, &y, &n);
- if (ret != 2 || (std::size_t)n != str.size())
- {
- std::string msg; msg.reserve(64 + str.size());
- msg += "failed to parse string '";
- msg += str;
- msg += "' as Magnum::Vector2i";
- throw std::invalid_argument(msg);
- }
- val = { x, y };
-}
-
-} // namespace nlohmann
template<typename t>
struct json_helper final {
@@ -59,7 +21,7 @@ std::tuple<t, bool> json_helper<t>::from_json(const std::filesystem::path& pathn
try {
s.open(pathname, std::ios_base::in);
} catch (const std::ios::failure& e) {
- Error{Error::Flag::NoSpace} << "failed to open " << pathname << ": " << e.what();
+ Error{Error::Flag::NoSpace} << "failed to open '" << pathname << "': " << e.what();
return { {}, false };
}
t ret;
@@ -69,7 +31,7 @@ std::tuple<t, bool> json_helper<t>::from_json(const std::filesystem::path& pathn
using nlohmann::from_json;
from_json(j, ret);
} catch (const std::exception& e) {
- Error{Error::Flag::NoSpace} << "failed to parse " << pathname << ": " << e.what();
+ Error{Error::Flag::NoSpace} << "failed to parse '" << pathname << "': " << e.what();
return { {}, false };
}
return { std::move(ret), true };
@@ -86,13 +48,13 @@ bool json_helper<t>::to_json(const t& self, const std::filesystem::path& pathnam
try {
s.open(pathname, std::ios_base::out | std::ios_base::trunc);
} catch (const std::ios::failure& e) {
- Error{} << "failed to open" << pathname << "for writing:" << e.what();
+ Error{Error::Flag::NoSpace} << "failed to open '" << pathname << "' for writing: " << e.what();
return false;
}
s << j.dump(4);
s.flush();
} catch (const std::exception& e) {
- Error{Error::Flag::NoSpace} << "failed writing to " << pathname << ": " << e.what();
+ Error{Error::Flag::NoSpace} << "failed writing to '" << pathname << "': " << e.what();
return false;
}
diff --git a/serialize/vector.hpp b/serialize/vector.hpp
new file mode 100644
index 00000000..39924a9b
--- /dev/null
+++ b/serialize/vector.hpp
@@ -0,0 +1,41 @@
+#include <cstdio>
+#include <string>
+#include <exception>
+#include <Magnum/Magnum.h>
+#include <Magnum/Math/Vector2.h>
+#include <nlohmann/json.hpp>
+
+namespace nlohmann {
+
+template<typename t>
+struct adl_serializer<Magnum::Math::Vector2<t>> final {
+ static void to_json(json& j, const Magnum::Math::Vector2<t>& x);
+ static void from_json(const json& j, Magnum::Math::Vector2<t>& x);
+};
+
+template<typename t>
+void adl_serializer<Magnum::Math::Vector2<t>>::to_json(json& j, const Magnum::Math::Vector2<t>& val)
+{
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%d x %d", val[0], val[1]);
+ j = buf;
+}
+
+template<typename t>
+void adl_serializer<Magnum::Math::Vector2<t>>::from_json(const json& j, Magnum::Math::Vector2<t>& val)
+{
+ std::string str = j;
+ int x = 0, y = 0, n = 0;
+ int ret = std::sscanf(str.c_str(), "%d x %d%n", &x, &y, &n);
+ if (ret != 2 || (std::size_t)n != str.size())
+ {
+ std::string msg; msg.reserve(64 + str.size());
+ msg += "failed to parse string '";
+ msg += str;
+ msg += "' as Magnum::Vector2i";
+ throw std::invalid_argument(msg);
+ }
+ val = { x, y };
+}
+
+} // namespace nlohmann