Files
rogue/source/cli/args.cpp
2026-04-16 23:27:01 -03:00

104 lines
2.8 KiB
C++

#include "args.hpp"
#include <charconv>
#include <format>
#include <stdexcept>
namespace rog::cli {
args parse(int argc, char **argv) {
args result{};
result.extent = {512, 512};
result.samples_per_pixel = 256;
if (argc < 2) {
throw std::runtime_error("no scene provided");
}
std::vector<std::string_view> args_view(argv + 1,
argv + argc); // skip program name
for (size_t i = 0; i < args_view.size(); ++i) {
std::string_view arg = args_view[i];
if (arg == "--help" || arg == "-h" || arg == "-?") {
result.help = true;
return result;
}
if (arg[0] != '-' && result.scene_path.empty()) {
result.scene_path = std::filesystem::path(arg);
continue;
}
if (arg == "--width" || arg == "-w") {
if (i + 1 >= args_view.size()) {
throw std::runtime_error("error: --width requires a value");
}
const auto val = args_view[++i];
uint32_t w = 0;
std::from_chars(val.data(), val.data() + val.size(), w);
result.extent.x = w;
continue;
}
if (arg == "--height" || (arg == "-h" && i + 1 < args_view.size() &&
args_view[i + 1][0] != '-')) {
if (i + 1 >= args_view.size()) {
throw std::runtime_error("error: --height requires a value");
}
const auto val = args_view[++i];
uint32_t h = 0;
std::from_chars(val.data(), val.data() + val.size(), h);
result.extent.y = h;
continue;
}
if (arg == "--spp") {
if (i + 1 >= args_view.size()) {
throw std::runtime_error("error: --spp requires a value");
}
const auto val = args_view[++i];
uint32_t spp = 0;
std::from_chars(val.data(), val.data() + val.size(), spp);
result.samples_per_pixel = spp;
continue;
}
if (arg == "--blender") {
if (i + 1 >= args_view.size()) {
throw std::runtime_error("error: --blender requires a path");
}
result.blender_path = std::filesystem::path(args_view[++i]);
continue;
}
if (arg[0] == '-') {
throw std::runtime_error(std::format("error: unknown option '{}'", arg));
}
}
return result;
}
std::string_view help_message() noexcept {
return R"(Usage: rogue [OPTIONS] <scene>
positional:
<scene> Path to .glb or .blend file (required)
options:
-w, --width <uint> Render width (default: 512)
-h, --height <uint> Render height (default: 512)
--spp <uint> Samples per pixel (default: 256)
--blender <path> Custom path to Blender executable
--help Show this help message
examples:
rogue scene.glb
rogue my_scene.blend --interactive
rogue scene.blend -w 1920 -h 1080 --spp 1024
)";
}
} // namespace rog::cli