diff --git a/tools/editor/cli_arg_parse.hpp b/tools/editor/cli_arg_parse.hpp new file mode 100644 index 00000000..2c920cec --- /dev/null +++ b/tools/editor/cli_arg_parse.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include +#include +#include + +namespace wowee { +namespace editor { +namespace cli { + +// Common pattern across cli_gen_texture and cli_gen_mesh handlers: +// "if there's another arg AND it doesn't look like a switch, parse +// it into ; otherwise leave at its default". 465+ copies +// across the two files were each writing this 3-line block manually. +// +// Each helper silently no-ops on parse failure so the caller's +// default value is preserved — matches the prior try/catch +// behavior exactly. + +inline bool parseOptArg(int& i, int argc, char** argv) { + return i + 1 < argc && argv[i + 1][0] != '-'; +} + +inline void parseOptInt(int& i, int argc, char** argv, int& value) { + if (parseOptArg(i, argc, argv)) { + try { value = std::stoi(argv[++i]); } catch (...) {} + } +} + +inline void parseOptFloat(int& i, int argc, char** argv, float& value) { + if (parseOptArg(i, argc, argv)) { + try { value = std::stof(argv[++i]); } catch (...) {} + } +} + +inline void parseOptUint(int& i, int argc, char** argv, uint32_t& value) { + if (parseOptArg(i, argc, argv)) { + try { value = static_cast(std::stoul(argv[++i])); } + catch (...) {} + } +} + +} // namespace cli +} // namespace editor +} // namespace wowee diff --git a/tools/editor/cli_gen_mesh.cpp b/tools/editor/cli_gen_mesh.cpp index e226147a..f2d7b84c 100644 --- a/tools/editor/cli_gen_mesh.cpp +++ b/tools/editor/cli_gen_mesh.cpp @@ -1,5 +1,6 @@ #include "cli_gen_mesh.hpp" #include "cli_box_emitter.hpp" +#include "cli_arg_parse.hpp" #include "pipeline/wowee_model.hpp" #include @@ -36,18 +37,10 @@ int handleRock(int& i, int argc, char** argv) { float roughness = 0.25f; // 0..1, fraction of radius int subdiv = 2; // 0=8 tris, 1=32, 2=128, 3=512 uint32_t seed = 1; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { radius = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { roughness = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { subdiv = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } + parseOptFloat(i, argc, argv, radius); + parseOptFloat(i, argc, argv, roughness); + parseOptInt(i, argc, argv, subdiv); + parseOptUint(i, argc, argv, seed); if (radius <= 0 || roughness < 0 || roughness > 1 || subdiv < 0 || subdiv > 4) { std::fprintf(stderr, @@ -184,18 +177,10 @@ int handlePillar(int& i, int argc, char** argv) { float height = 4.0f; int flutes = 12; float capScale = 1.25f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { radius = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { flutes = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { capScale = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, radius); + parseOptFloat(i, argc, argv, height); + parseOptInt(i, argc, argv, flutes); + parseOptFloat(i, argc, argv, capScale); if (radius <= 0 || height <= 0 || flutes < 4 || flutes > 64 || capScale < 1.0f || capScale > 4.0f) { @@ -323,18 +308,10 @@ int handleBridge(int& i, int argc, char** argv) { float width = 2.0f; // along Z int planks = 6; // plank count across the length float railHeight = 1.0f; // rail height above deck (0 = no rails) - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { length = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { planks = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { railHeight = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, length); + parseOptFloat(i, argc, argv, width); + parseOptInt(i, argc, argv, planks); + parseOptFloat(i, argc, argv, railHeight); if (length <= 0 || width <= 0 || planks < 1 || planks > 64 || railHeight < 0 || railHeight > 4.0f) { @@ -428,18 +405,10 @@ int handleTower(int& i, int argc, char** argv) { float height = 8.0f; int battlements = 8; // merlons around the rim float battlementH = 0.5f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { radius = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { battlements = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { battlementH = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, radius); + parseOptFloat(i, argc, argv, height); + parseOptInt(i, argc, argv, battlements); + parseOptFloat(i, argc, argv, battlementH); if (radius <= 0 || height <= 0 || battlements < 4 || battlements > 64 || battlementH < 0 || battlementH > 4.0f) { @@ -578,18 +547,10 @@ int handleHouse(int& i, int argc, char** argv) { float depth = 4.0f; // along Z float height = 3.0f; // wall height (Y) float roofH = 2.0f; // pyramid above walls - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { depth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { roofH = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, depth); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, roofH); if (width <= 0 || depth <= 0 || height <= 0 || roofH < 0 || roofH > 20.0f) { std::fprintf(stderr, @@ -692,18 +653,10 @@ int handleFountain(int& i, int argc, char** argv) { float basinH = 0.5f; float spoutR = 0.2f; float spoutH = 1.5f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { basinR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { basinH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { spoutR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { spoutH = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, basinR); + parseOptFloat(i, argc, argv, basinH); + parseOptFloat(i, argc, argv, spoutR); + parseOptFloat(i, argc, argv, spoutH); if (basinR <= 0 || basinH <= 0 || spoutR <= 0 || spoutH <= 0 || spoutR >= basinR) { std::fprintf(stderr, @@ -799,15 +752,9 @@ int handleStatue(int& i, int argc, char** argv) { float pedSize = 1.0f; // pedestal width and depth float bodyH = 2.5f; // body cylinder height float headR = 0.4f; // head sphere radius - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { pedSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bodyH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { headR = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, pedSize); + parseOptFloat(i, argc, argv, bodyH); + parseOptFloat(i, argc, argv, headR); if (pedSize <= 0 || bodyH <= 0 || headR <= 0) { std::fprintf(stderr, "gen-mesh-statue: all dims must be positive\n"); @@ -947,18 +894,10 @@ int handleAltar(int& i, int argc, char** argv) { float topH = 0.3f; // top altar disc height int steps = 3; // base steps below the top float stepStride = 0.3f; // each step grows R by this much, shrinks H - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { topR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { topH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { steps = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stepStride = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, topR); + parseOptFloat(i, argc, argv, topH); + parseOptInt(i, argc, argv, steps); + parseOptFloat(i, argc, argv, stepStride); if (topR <= 0 || topH <= 0 || steps < 0 || steps > 16 || stepStride <= 0 || stepStride > 5.0f) { std::fprintf(stderr, @@ -1069,18 +1008,10 @@ int handlePortal(int& i, int argc, char** argv) { float height = 4.0f; // total Y float postThick = 0.4f; // post width in X and Z float lintelH = 0.5f; // top lintel height (Y) - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postThick = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { lintelH = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, postThick); + parseOptFloat(i, argc, argv, lintelH); if (width <= 0 || height <= 0 || postThick <= 0 || lintelH < 0 || postThick * 2 >= width || lintelH > height) { @@ -1153,18 +1084,10 @@ int handleArchway(int& i, int argc, char** argv) { float pillarH = 3.0f; // pillar height (Y) float thickness = 0.4f; // pillar radius and arch radial thickness int archSegs = 12; // segments around the half-circle - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { pillarH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { thickness = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { archSegs = std::stoi(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, pillarH); + parseOptFloat(i, argc, argv, thickness); + parseOptInt(i, argc, argv, archSegs); if (width <= 0 || pillarH <= 0 || thickness <= 0 || archSegs < 4 || archSegs > 64 || thickness * 4 >= width) { @@ -1330,18 +1253,10 @@ int handleBarrel(int& i, int argc, char** argv) { float midR = 0.5f; // radius at the middle bulge float height = 1.0f; float hoopThick = 0.06f; // hoop band radial protrusion - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { topR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { midR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { hoopThick = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, topR); + parseOptFloat(i, argc, argv, midR); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, hoopThick); if (topR <= 0 || midR <= 0 || height <= 0 || hoopThick < 0 || hoopThick > 0.5f) { std::fprintf(stderr, @@ -1442,18 +1357,10 @@ int handleChest(int& i, int argc, char** argv) { float depth = 0.9f; // along Z float bodyH = 0.9f; // body box height float lidH = 0.25f; // lid height above body - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { depth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bodyH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { lidH = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, depth); + parseOptFloat(i, argc, argv, bodyH); + parseOptFloat(i, argc, argv, lidH); if (width <= 0 || depth <= 0 || bodyH <= 0 || lidH < 0) { std::fprintf(stderr, "gen-mesh-chest: width/depth/bodyH > 0, lidH >= 0\n"); @@ -1537,18 +1444,10 @@ int handleAnvil(int& i, int argc, char** argv) { float width = 0.4f; // along Z float hornLen = 0.5f; // horn extending past face float bodyH = 0.5f; // total height - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { length = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { hornLen = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bodyH = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, length); + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, hornLen); + parseOptFloat(i, argc, argv, bodyH); if (length <= 0 || width <= 0 || hornLen < 0 || bodyH <= 0) { std::fprintf(stderr, "gen-mesh-anvil: length/width/bodyH > 0, hornLen >= 0\n"); @@ -1681,15 +1580,9 @@ int handleStairs(int& i, int argc, char** argv) { "gen-mesh-stairs: steps %d out of range (1..256)\n", steps); return 1; } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stepHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stepDepth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, stepHeight); + parseOptFloat(i, argc, argv, stepDepth); + parseOptFloat(i, argc, argv, width); if (stepHeight <= 0 || stepDepth <= 0 || width <= 0) { std::fprintf(stderr, "gen-mesh-stairs: dimensions must be positive\n"); @@ -1798,9 +1691,7 @@ int handleGrid(int& i, int argc, char** argv) { return 1; } float size = 1.0f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { size = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, size); if (size <= 0.0f) { std::fprintf(stderr, "gen-mesh-grid: size must be positive\n"); @@ -1879,12 +1770,8 @@ int handleDisc(int& i, int argc, char** argv) { std::string womBase = argv[++i]; float radius = 1.0f; int segments = 32; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { radius = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { segments = std::stoi(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, radius); + parseOptInt(i, argc, argv, segments); if (radius <= 0.0f || segments < 3 || segments > 1024) { std::fprintf(stderr, "gen-mesh-disc: radius must be positive, segments 3..1024\n"); @@ -1960,18 +1847,10 @@ int handleTube(int& i, int argc, char** argv) { float innerR = 0.7f; float height = 2.0f; int segments = 24; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { outerR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { innerR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { segments = std::stoi(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, outerR); + parseOptFloat(i, argc, argv, innerR); + parseOptFloat(i, argc, argv, height); + parseOptInt(i, argc, argv, segments); if (outerR <= 0 || innerR <= 0 || innerR >= outerR || height <= 0 || segments < 3 || segments > 1024) { std::fprintf(stderr, @@ -2132,18 +2011,10 @@ int handleCapsule(int& i, int argc, char** argv) { float cylHeight = 1.0f; int segments = 16; int stacks = 8; // per hemisphere - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { radius = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cylHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { segments = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stacks = std::stoi(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, radius); + parseOptFloat(i, argc, argv, cylHeight); + parseOptInt(i, argc, argv, segments); + parseOptInt(i, argc, argv, stacks); if (radius <= 0 || cylHeight < 0 || segments < 3 || segments > 1024 || stacks < 1 || stacks > 256) { @@ -2290,21 +2161,11 @@ int handleArch(int& i, int argc, char** argv) { float thickness = 0.2f; // column thickness (X) float depth = 0.3f; // Y extrusion int segments = 12; // arch curve segments - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { openingW = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { openingH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { thickness = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { depth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { segments = std::stoi(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, openingW); + parseOptFloat(i, argc, argv, openingH); + parseOptFloat(i, argc, argv, thickness); + parseOptFloat(i, argc, argv, depth); + parseOptInt(i, argc, argv, segments); if (openingW <= 0 || openingH <= 0 || thickness <= 0 || depth <= 0 || segments < 2 || segments > 256) { @@ -2419,15 +2280,9 @@ int handlePyramid(int& i, int argc, char** argv) { int sides = 4; float baseR = 1.0f; float height = 1.0f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { sides = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, sides); + parseOptFloat(i, argc, argv, baseR); + parseOptFloat(i, argc, argv, height); if (sides < 3 || sides > 256 || baseR <= 0 || height <= 0) { std::fprintf(stderr, "gen-mesh-pyramid: sides 3..256, baseR > 0, height > 0\n"); @@ -2527,18 +2382,10 @@ int handleFence(int& i, int argc, char** argv) { float spacing = 1.0f; float postH = 1.0f; float rt = 0.05f; // rail/post thickness - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { posts = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { spacing = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { rt = std::stof(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, posts); + parseOptFloat(i, argc, argv, spacing); + parseOptFloat(i, argc, argv, postH); + parseOptFloat(i, argc, argv, rt); if (posts < 2 || posts > 256 || spacing <= 0 || postH <= 0 || rt <= 0) { std::fprintf(stderr, @@ -2622,15 +2469,9 @@ int handleTree(int& i, int argc, char** argv) { float trunkR = 0.1f; float trunkH = 2.0f; float foliR = 0.7f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { trunkR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { trunkH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { foliR = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, trunkR); + parseOptFloat(i, argc, argv, trunkH); + parseOptFloat(i, argc, argv, foliR); if (trunkR <= 0 || trunkH <= 0 || foliR <= 0) { std::fprintf(stderr, "gen-mesh-tree: trunkR / trunkH / foliR must be positive\n"); @@ -2750,9 +2591,7 @@ int handleMeshDispatch(int& i, int argc, char** argv) { std::string womBase = argv[++i]; std::string shape = argv[++i]; float size = 1.0f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { size = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, size); if (size <= 0.0f) { std::fprintf(stderr, "gen-mesh: size must be positive (got %g)\n", size); @@ -3215,15 +3054,9 @@ int handleMushroom(int& i, int argc, char** argv) { float stalkR = 0.1f; float stalkH = 0.6f; float capR = 0.4f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stalkR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stalkH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { capR = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, stalkR); + parseOptFloat(i, argc, argv, stalkH); + parseOptFloat(i, argc, argv, capR); if (stalkR <= 0 || stalkH <= 0 || capR <= 0) { std::fprintf(stderr, "gen-mesh-mushroom: all dims must be positive\n"); @@ -3345,18 +3178,10 @@ int handleCart(int& i, int argc, char** argv) { float bedWidth = 0.8f; // along Z float bedH = 0.5f; // bed height (Y) float wheelR = 0.35f; // wheel radius - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bedLen = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bedWidth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bedH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { wheelR = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, bedLen); + parseOptFloat(i, argc, argv, bedWidth); + parseOptFloat(i, argc, argv, bedH); + parseOptFloat(i, argc, argv, wheelR); if (bedLen <= 0 || bedWidth <= 0 || bedH <= 0 || wheelR <= 0) { std::fprintf(stderr, "gen-mesh-cart: all dims must be positive\n"); @@ -3472,18 +3297,10 @@ int handleBanner(int& i, int argc, char** argv) { float poleR = 0.05f; float flagW = 0.8f; // along -Z (drape direction) float flagH = 1.2f; // along Y (down from top) - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { poleH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { poleR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { flagW = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { flagH = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, poleH); + parseOptFloat(i, argc, argv, poleR); + parseOptFloat(i, argc, argv, flagW); + parseOptFloat(i, argc, argv, flagH); if (poleH <= 0 || poleR <= 0 || flagW <= 0 || flagH <= 0 || flagH > poleH) { std::fprintf(stderr, @@ -3588,18 +3405,10 @@ int handleGrave(int& i, int argc, char** argv) { float tabletH = 1.0f; // along Y float tabletT = 0.15f; // along Z (thickness) float baseW = 0.8f; // base wider than tablet - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { tabletW = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { tabletH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { tabletT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseW = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, tabletW); + parseOptFloat(i, argc, argv, tabletH); + parseOptFloat(i, argc, argv, tabletT); + parseOptFloat(i, argc, argv, baseW); if (tabletW <= 0 || tabletH <= 0 || tabletT <= 0 || baseW <= 0 || baseW < tabletW) { std::fprintf(stderr, @@ -3663,18 +3472,10 @@ int handleBench(int& i, int argc, char** argv) { float seatY = 0.5f; // seat top height float seatT = 0.06f; // seat plank thickness (Y) float seatW = 0.4f; // seat width (Z) - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { length = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seatY = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seatT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seatW = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, length); + parseOptFloat(i, argc, argv, seatY); + parseOptFloat(i, argc, argv, seatT); + parseOptFloat(i, argc, argv, seatW); if (length <= 0 || seatY <= 0 || seatT <= 0 || seatW <= 0 || seatT > seatY) { std::fprintf(stderr, @@ -3737,18 +3538,10 @@ int handleShrine(int& i, int argc, char** argv) { float pillarH = 2.0f; // pillar height float pillarR = 0.10f; // pillar radius float roofT = 0.15f; // roof thickness - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { size = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { pillarH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { pillarR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { roofT = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, size); + parseOptFloat(i, argc, argv, pillarH); + parseOptFloat(i, argc, argv, pillarR); + parseOptFloat(i, argc, argv, roofT); if (size <= 0 || pillarH <= 0 || pillarR <= 0 || roofT <= 0 || pillarR * 2 >= size) { std::fprintf(stderr, @@ -3850,15 +3643,9 @@ int handleTotem(int& i, int argc, char** argv) { float baseW = 0.5f; // base block half-width × 2 int segments = 5; // number of stacked blocks float segH = 0.5f; // height of each block - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseW = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { segments = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { segH = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, baseW); + parseOptInt(i, argc, argv, segments); + parseOptFloat(i, argc, argv, segH); if (baseW <= 0 || segH <= 0 || segments < 1 || segments > 32) { std::fprintf(stderr, "gen-mesh-totem: dims > 0, segments 1..32\n"); @@ -3916,18 +3703,10 @@ int handleCage(int& i, int argc, char** argv) { float height = 2.0f; int barsPerSide = 5; float barRadius = 0.04f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { barsPerSide = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { barRadius = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, height); + parseOptInt(i, argc, argv, barsPerSide); + parseOptFloat(i, argc, argv, barRadius); if (width <= 0 || height <= 0 || barRadius <= 0 || barsPerSide < 0 || barsPerSide > 64) { std::fprintf(stderr, @@ -4011,18 +3790,10 @@ int handleThrone(int& i, int argc, char** argv) { float seatH = 0.5f; // top of seat above pedestal float backH = 1.5f; // backrest extends this above seat float pedSize = 1.2f; // pedestal width = depth - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seatW = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seatH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { backH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { pedSize = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, seatW); + parseOptFloat(i, argc, argv, seatH); + parseOptFloat(i, argc, argv, backH); + parseOptFloat(i, argc, argv, pedSize); if (seatW <= 0 || seatH <= 0 || backH <= 0 || pedSize <= 0 || pedSize < seatW) { std::fprintf(stderr, @@ -4099,15 +3870,9 @@ int handleCoffin(int& i, int argc, char** argv) { float length = 2.0f; // along Z float width = 0.8f; // shoulder width along X float height = 0.6f; // along Y - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { length = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, length); + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, height); if (length <= 0 || width <= 0 || height <= 0) { std::fprintf(stderr, "gen-mesh-coffin: length/width/height must be > 0\n"); @@ -4236,18 +4001,10 @@ int handleArchwayDouble(int& i, int argc, char** argv) { float openingHeight = 2.40f; // post height under lintel float postT = 0.18f; float lintelT = 0.20f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { openingWidth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { openingHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { lintelT = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, openingWidth); + parseOptFloat(i, argc, argv, openingHeight); + parseOptFloat(i, argc, argv, postT); + parseOptFloat(i, argc, argv, lintelT); if (openingWidth <= 0 || openingHeight <= 0 || postT <= 0 || lintelT <= 0) { std::fprintf(stderr, @@ -4324,18 +4081,10 @@ int handleBrazier(int& i, int argc, char** argv) { float stemHeight = 0.80f; float stemT = 0.10f; float baseSize = 0.35f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bowlSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stemHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stemT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseSize = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, bowlSize); + parseOptFloat(i, argc, argv, stemHeight); + parseOptFloat(i, argc, argv, stemT); + parseOptFloat(i, argc, argv, baseSize); if (bowlSize <= 0 || stemHeight <= 0 || stemT <= 0 || baseSize <= 0 || stemT >= baseSize || stemT >= bowlSize) { std::fprintf(stderr, @@ -4421,18 +4170,10 @@ int handlePodium(int& i, int argc, char** argv) { float baseHeight = 0.20f; int stepCount = 3; // total stepped tiers (incl. top) float lecternSize = 0.30f; // lectern at the very top - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stepCount = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { lecternSize = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, baseSize); + parseOptFloat(i, argc, argv, baseHeight); + parseOptInt(i, argc, argv, stepCount); + parseOptFloat(i, argc, argv, lecternSize); if (baseSize <= 0 || baseHeight <= 0 || lecternSize <= 0 || stepCount < 2 || stepCount > 8) { std::fprintf(stderr, @@ -4508,18 +4249,10 @@ int handleSundial(int& i, int argc, char** argv) { float baseHeight = 0.06f; float gnomonHeight = 0.35f; float gnomonT = 0.04f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { gnomonHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { gnomonT = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, baseSize); + parseOptFloat(i, argc, argv, baseHeight); + parseOptFloat(i, argc, argv, gnomonHeight); + parseOptFloat(i, argc, argv, gnomonT); if (baseSize <= 0 || baseHeight <= 0 || gnomonHeight <= 0 || gnomonT <= 0 || gnomonT * 2 >= baseSize) { @@ -4600,21 +4333,11 @@ int handleScarecrow(int& i, int argc, char** argv) { float postT = 0.06f; float headSize = 0.22f; float hatSize = 0.32f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bodyHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { armSpan = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { headSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { hatSize = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, bodyHeight); + parseOptFloat(i, argc, argv, armSpan); + parseOptFloat(i, argc, argv, postT); + parseOptFloat(i, argc, argv, headSize); + parseOptFloat(i, argc, argv, hatSize); if (bodyHeight <= 0 || armSpan <= 0 || postT <= 0 || headSize <= 0 || hatSize <= 0) { std::fprintf(stderr, "gen-mesh-scarecrow: all dims must be > 0\n"); @@ -4698,21 +4421,11 @@ int handleWeathervane(int& i, int argc, char** argv) { float baseSize = 0.30f; float armLen = 0.40f; // half-length of each cross arm float arrowLen = 0.55f; // half-length of the arrow body - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { armLen = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { arrowLen = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, postHeight); + parseOptFloat(i, argc, argv, postT); + parseOptFloat(i, argc, argv, baseSize); + parseOptFloat(i, argc, argv, armLen); + parseOptFloat(i, argc, argv, arrowLen); if (postHeight <= 0 || postT <= 0 || baseSize <= 0 || armLen <= 0 || arrowLen <= 0 || postT >= baseSize) { std::fprintf(stderr, @@ -4798,15 +4511,9 @@ int handleBeehive(int& i, int argc, char** argv) { float baseWidth = 0.70f; // bottom tier width float height = 0.85f; // total dome height (excluding base plate) float plateH = 0.05f; // optional foundation plate thickness - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseWidth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { plateH = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, baseWidth); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, plateH); if (baseWidth <= 0 || height <= 0 || plateH < 0) { std::fprintf(stderr, "gen-mesh-beehive: baseWidth/height > 0; plateH >= 0\n"); @@ -4888,18 +4595,10 @@ int handleGate(int& i, int argc, char** argv) { float postHeight = 1.30f; // post height (= gate frame height) float postT = 0.10f; // post square cross-section float railT = 0.06f; // rail square cross-section - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { openingWidth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { railT = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, openingWidth); + parseOptFloat(i, argc, argv, postHeight); + parseOptFloat(i, argc, argv, postT); + parseOptFloat(i, argc, argv, railT); if (openingWidth <= 0 || postHeight <= 0 || postT <= 0 || railT <= 0 || railT >= postHeight / 4) { std::fprintf(stderr, @@ -4973,15 +4672,9 @@ int handleCauldron(int& i, int argc, char** argv) { float rimWidth = 0.80f; // top-rim extent (widest dim) float bodyHeight = 0.70f; // total height excluding legs float legHeight = 0.10f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { rimWidth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bodyHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { legHeight = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, rimWidth); + parseOptFloat(i, argc, argv, bodyHeight); + parseOptFloat(i, argc, argv, legHeight); if (rimWidth <= 0 || bodyHeight <= 0 || legHeight <= 0) { std::fprintf(stderr, "gen-mesh-cauldron: all dims must be > 0\n"); @@ -5062,18 +4755,10 @@ int handleStool(int& i, int argc, char** argv) { float seatT = 0.04f; // seat thickness float legHeight = 0.45f; float legT = 0.04f; // square leg cross-section - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seatSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seatT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { legHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { legT = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, seatSize); + parseOptFloat(i, argc, argv, seatT); + parseOptFloat(i, argc, argv, legHeight); + parseOptFloat(i, argc, argv, legT); if (seatSize <= 0 || seatT <= 0 || legHeight <= 0 || legT <= 0 || legT * 2 >= seatSize) { std::fprintf(stderr, @@ -5137,12 +4822,8 @@ int handleCrate(int& i, int argc, char** argv) { std::string womBase = argv[++i]; float size = 0.80f; // cube side length float postRadius = 0.05f; // half-thickness of corner posts - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { size = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postRadius = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, size); + parseOptFloat(i, argc, argv, postRadius); if (size <= 0 || postRadius <= 0 || postRadius * 4 >= size) { std::fprintf(stderr, "gen-mesh-crate: size/postRadius > 0; postRadius < size/4\n"); @@ -5208,18 +4889,10 @@ int handleTombstone(int& i, int argc, char** argv) { float height = 1.10f; // total tombstone height including base + crown float depth = 0.18f; // along Z (slab thickness) float baseScale = 1.45f; // base extends this much beyond slab in X & Z - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { depth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseScale = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, depth); + parseOptFloat(i, argc, argv, baseScale); if (width <= 0 || height <= 0 || depth <= 0 || baseScale < 1.0f || baseScale > 5.0f) { std::fprintf(stderr, @@ -5296,21 +4969,11 @@ int handleMailbox(int& i, int argc, char** argv) { float boxLength = 0.45f; // along Z float boxWidth = 0.20f; // along X float boxHeight = 0.20f; // along Y - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postThickness = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { boxLength = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { boxWidth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { boxHeight = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, postHeight); + parseOptFloat(i, argc, argv, postThickness); + parseOptFloat(i, argc, argv, boxLength); + parseOptFloat(i, argc, argv, boxWidth); + parseOptFloat(i, argc, argv, boxHeight); if (postHeight <= 0 || postThickness <= 0 || boxLength <= 0 || boxWidth <= 0 || boxHeight <= 0) { std::fprintf(stderr, @@ -5399,21 +5062,11 @@ int handleSignpost(int& i, int argc, char** argv) { float baseSize = 0.30f; float signWidth = 0.80f; // along Z (perpendicular to pole face) float signHeight = 0.35f; // along Y - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postThickness = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { signWidth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { signHeight = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, postHeight); + parseOptFloat(i, argc, argv, postThickness); + parseOptFloat(i, argc, argv, baseSize); + parseOptFloat(i, argc, argv, signWidth); + parseOptFloat(i, argc, argv, signHeight); if (postHeight <= 0 || postThickness <= 0 || baseSize <= 0 || signWidth <= 0 || signHeight <= 0 || postThickness >= baseSize) { @@ -5498,21 +5151,11 @@ int handleWell(int& i, int argc, char** argv) { float wallT = 0.15f; // wall thickness float postH = 1.6f; // roof post height above wall float postT = 0.12f; // roof post thickness (square) - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { outerSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { wallH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { wallT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postT = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, outerSize); + parseOptFloat(i, argc, argv, wallH); + parseOptFloat(i, argc, argv, wallT); + parseOptFloat(i, argc, argv, postH); + parseOptFloat(i, argc, argv, postT); if (outerSize <= 0 || wallH <= 0 || wallT <= 0 || postH <= 0 || postT <= 0 || wallT * 2 >= outerSize) { std::fprintf(stderr, @@ -5603,21 +5246,11 @@ int handleLadder(int& i, int argc, char** argv) { int rungs = 8; float railT = 0.06f; float rungT = 0.04f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { rungs = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { railT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { rungT = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, width); + parseOptInt(i, argc, argv, rungs); + parseOptFloat(i, argc, argv, railT); + parseOptFloat(i, argc, argv, rungT); if (height <= 0 || width <= 0 || railT <= 0 || rungT <= 0 || rungs < 2 || rungs > 64 || railT * 2 >= width) { std::fprintf(stderr, @@ -5690,24 +5323,12 @@ int handleBed(int& i, int argc, char** argv) { float matThick = 0.20f; float headH = 1.0f; // headboard height above mattress float footH = 0.4f; // footboard height above mattress - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { length = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { legHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { matThick = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { headH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { footH = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, length); + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, legHeight); + parseOptFloat(i, argc, argv, matThick); + parseOptFloat(i, argc, argv, headH); + parseOptFloat(i, argc, argv, footH); if (length <= 0 || width <= 0 || legHeight <= 0 || matThick <= 0 || headH <= 0 || footH <= 0) { std::fprintf(stderr, "gen-mesh-bed: all dims must be > 0\n"); @@ -5796,21 +5417,11 @@ int handleLamppost(int& i, int argc, char** argv) { float baseSize = 0.4f; float lanternSize = 0.35f; float lanternHeight = 0.5f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postHeight = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postThickness = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { lanternSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { lanternHeight = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, postHeight); + parseOptFloat(i, argc, argv, postThickness); + parseOptFloat(i, argc, argv, baseSize); + parseOptFloat(i, argc, argv, lanternSize); + parseOptFloat(i, argc, argv, lanternHeight); if (postHeight <= 0 || postThickness <= 0 || baseSize <= 0 || lanternSize <= 0 || lanternHeight <= 0 || postThickness >= baseSize || postThickness >= lanternSize) { @@ -5895,21 +5506,11 @@ int handleTable(int& i, int argc, char** argv) { float height = 0.85f; // along Y (top of tabletop) float legT = 0.10f; // leg thickness (square cross-section) float topT = 0.06f; // tabletop thickness - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { depth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { legT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { topT = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, depth); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, legT); + parseOptFloat(i, argc, argv, topT); if (width <= 0 || depth <= 0 || height <= 0 || legT <= 0 || topT <= 0 || legT * 2 > width || legT * 2 > depth || topT >= height) { @@ -5977,18 +5578,10 @@ int handleBookshelf(int& i, int argc, char** argv) { float height = 2.0f; float depth = 0.4f; int shelves = 4; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { depth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { shelves = std::stoi(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, depth); + parseOptInt(i, argc, argv, shelves); if (width <= 0 || height <= 0 || depth <= 0 || shelves < 2 || shelves > 12) { std::fprintf(stderr, @@ -6114,21 +5707,11 @@ int handleTent(int& i, int argc, char** argv) { float height = 0.9f; float doorH = 0.5f; float doorW = 0.4f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { length = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { doorH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { doorW = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, length); + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, doorH); + parseOptFloat(i, argc, argv, doorW); if (length <= 0 || width <= 0 || height <= 0 || doorH < 0 || doorH >= height || doorW < 0 || doorW >= width) { @@ -6257,18 +5840,10 @@ int handleBedroll(int& i, int argc, char** argv) { float radius = 0.16f; int sides = 12; float pillowSize = 0.18f; // 0 → no pillow - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { length = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { radius = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { sides = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { pillowSize = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, length); + parseOptFloat(i, argc, argv, radius); + parseOptInt(i, argc, argv, sides); + parseOptFloat(i, argc, argv, pillowSize); if (length <= 0 || radius <= 0 || sides < 6 || sides > 64 || pillowSize < 0 || pillowSize >= length * 0.5f) { std::fprintf(stderr, @@ -6387,21 +5962,11 @@ int handleChimney(int& i, int argc, char** argv) { float height = 1.8f; float capH = 0.10f; float capExtra = 0.05f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { depth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { capH = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { capExtra = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, depth); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, capH); + parseOptFloat(i, argc, argv, capExtra); if (width <= 0 || depth <= 0 || height <= 0 || capH < 0 || capH >= height || capExtra < 0) { std::fprintf(stderr, @@ -6465,24 +6030,12 @@ int handlePergola(int& i, int argc, char** argv) { float postR = 0.06f; float beamT = 0.05f; int crossbeams = 5; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { length = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { beamT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { crossbeams = std::stoi(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, length); + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, postR); + parseOptFloat(i, argc, argv, beamT); + parseOptInt(i, argc, argv, crossbeams); if (length <= 0 || width <= 0 || height <= 0 || postR <= 0 || postR * 2 >= std::min(length, width) || beamT <= 0 || crossbeams < 0 || crossbeams > 32) { @@ -6568,24 +6121,12 @@ int handleDock(int& i, int argc, char** argv) { int pilingsPerSide = 3; float pilingW = 0.10f; float deckT = 0.10f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { length = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { pilingsPerSide = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { pilingW = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { deckT = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, length); + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, height); + parseOptInt(i, argc, argv, pilingsPerSide); + parseOptFloat(i, argc, argv, pilingW); + parseOptFloat(i, argc, argv, deckT); if (length <= 0 || width <= 0 || height <= 0 || deckT <= 0 || pilingW <= 0 || pilingW * 2 >= width || pilingsPerSide < 1 || pilingsPerSide > 16) { @@ -6654,18 +6195,10 @@ int handleHaystack(int& i, int argc, char** argv) { float height = 0.9f; int layers = 3; int sides = 12; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { baseR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { layers = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { sides = std::stoi(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, baseR); + parseOptFloat(i, argc, argv, height); + parseOptInt(i, argc, argv, layers); + parseOptInt(i, argc, argv, sides); if (baseR <= 0 || height <= 0 || layers < 2 || layers > 16 || sides < 6 || sides > 64) { @@ -6825,24 +6358,12 @@ int handleCanopy(int& i, int argc, char** argv) { float postR = 0.05f; float panelT = 0.03f; float drape = 0.15f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { width = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { depth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { height = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { postR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { panelT = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { drape = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, width); + parseOptFloat(i, argc, argv, depth); + parseOptFloat(i, argc, argv, height); + parseOptFloat(i, argc, argv, postR); + parseOptFloat(i, argc, argv, panelT); + parseOptFloat(i, argc, argv, drape); if (width <= 0 || depth <= 0 || height <= 0 || postR <= 0 || postR * 2 >= std::min(width, depth) || panelT <= 0 || drape < 0 || drape >= height) { @@ -6926,15 +6447,9 @@ int handleWoodpile(int& i, int argc, char** argv) { float logR = 0.10f; float logLen = 0.80f; int sides = 12; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { logR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { logLen = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { sides = std::stoi(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, logR); + parseOptFloat(i, argc, argv, logLen); + parseOptInt(i, argc, argv, sides); if (logR <= 0 || logLen <= 0 || sides < 6 || sides > 64) { std::fprintf(stderr, "gen-mesh-woodpile: dims > 0; sides 6..64\n"); @@ -7057,21 +6572,11 @@ int handleFirepit(int& i, int argc, char** argv) { float stoneSize = 0.10f; float logLen = 0.45f; float logThick = 0.05f; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { ringR = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stones = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stoneSize = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { logLen = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { logThick = std::stof(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, ringR); + parseOptInt(i, argc, argv, stones); + parseOptFloat(i, argc, argv, stoneSize); + parseOptFloat(i, argc, argv, logLen); + parseOptFloat(i, argc, argv, logThick); if (ringR <= 0 || stoneSize <= 0 || logLen <= 0 || logThick <= 0 || stones < 3 || stones > 64) { std::fprintf(stderr, diff --git a/tools/editor/cli_gen_texture.cpp b/tools/editor/cli_gen_texture.cpp index b8dab81d..90146c79 100644 --- a/tools/editor/cli_gen_texture.cpp +++ b/tools/editor/cli_gen_texture.cpp @@ -1,4 +1,5 @@ #include "cli_gen_texture.hpp" +#include "cli_arg_parse.hpp" #include #include @@ -68,18 +69,10 @@ int handleCobble(int& i, int argc, char** argv) { int stonePx = 24; uint32_t seed = 1; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stonePx = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, stonePx); + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || stonePx < 8 || stonePx > 512) { std::fprintf(stderr, @@ -198,18 +191,10 @@ int handleMarble(int& i, int argc, char** argv) { uint32_t seed = 1; float sharpness = 8.0f; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { sharpness = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptFloat(i, argc, argv, sharpness); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || sharpness < 1.0f || sharpness > 64.0f) { std::fprintf(stderr, @@ -296,18 +281,12 @@ int handleMetal(int& i, int argc, char** argv) { uint32_t seed = 1; std::string orientation = "horizontal"; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); if (i + 1 < argc && argv[i + 1][0] != '-') { orientation = argv[++i]; } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192) { std::fprintf(stderr, "gen-texture-metal: invalid dims (W/H 1..8192)\n"); @@ -404,18 +383,10 @@ int handleLeather(int& i, int argc, char** argv) { uint32_t seed = 1; int grainSize = 4; // average pebble cell size in px int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { grainSize = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, grainSize); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || grainSize < 2 || grainSize > 64) { std::fprintf(stderr, @@ -508,18 +479,10 @@ int handleSand(int& i, int argc, char** argv) { uint32_t seed = 1; int rippleSpacing = 24; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { rippleSpacing = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, rippleSpacing); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || rippleSpacing < 4 || rippleSpacing > 512) { std::fprintf(stderr, @@ -591,18 +554,10 @@ int handleSnow(int& i, int argc, char** argv) { uint32_t seed = 1; float density = 0.005f; // fraction of pixels that sparkle int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { density = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptFloat(i, argc, argv, density); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || density < 0.0f || density > 0.5f) { std::fprintf(stderr, @@ -679,18 +634,10 @@ int handleLava(int& i, int argc, char** argv) { uint32_t seed = 1; int crackScale = 32; // average cell size in px int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { crackScale = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, crackScale); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || crackScale < 8 || crackScale > 512) { std::fprintf(stderr, @@ -805,12 +752,8 @@ int handleGradient(int& i, int argc, char** argv) { i++; } } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192) { std::fprintf(stderr, "gen-texture-gradient: invalid size %dx%d (1..8192)\n", @@ -888,12 +831,8 @@ int handleNoise(int& i, int argc, char** argv) { try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192) { std::fprintf(stderr, "gen-texture-noise: invalid size %dx%d (1..8192)\n", @@ -969,12 +908,8 @@ int handleNoiseColor(int& i, int argc, char** argv) { try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192) { std::fprintf(stderr, "gen-texture-noise-color: invalid size %dx%d\n", W, H); @@ -1060,12 +995,8 @@ int handleRadial(int& i, int argc, char** argv) { std::string centerHex = argv[++i]; std::string edgeHex = argv[++i]; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192) { std::fprintf(stderr, "gen-texture-radial: invalid size %dx%d (1..8192)\n", @@ -1136,9 +1067,7 @@ int handleStripes(int& i, int argc, char** argv) { int stripePx = 16; std::string dir = "diagonal"; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stripePx = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, stripePx); if (i + 1 < argc && argv[i + 1][0] != '-') { std::string d = argv[i + 1]; std::transform(d.begin(), d.end(), d.begin(), @@ -1148,12 +1077,8 @@ int handleStripes(int& i, int argc, char** argv) { i++; } } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || stripePx < 1 || stripePx > 4096) { std::fprintf(stderr, @@ -1211,18 +1136,10 @@ int handleDots(int& i, int argc, char** argv) { std::string dotHex = argv[++i]; int radius = 8, spacing = 32; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { radius = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { spacing = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, radius); + parseOptInt(i, argc, argv, spacing); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || radius < 1 || radius > 1024 || spacing < 2 || spacing > 4096) { @@ -1285,15 +1202,9 @@ int handleRings(int& i, int argc, char** argv) { std::string bHex = argv[++i]; int ringPx = 16; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { ringPx = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, ringPx); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || ringPx < 1 || ringPx > 4096) { std::fprintf(stderr, @@ -1353,15 +1264,9 @@ int handleChecker(int& i, int argc, char** argv) { std::string bHex = argv[++i]; int cellPx = 32; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cellPx = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, cellPx); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || cellPx < 1 || cellPx > 4096) { std::fprintf(stderr, @@ -1415,21 +1320,11 @@ int handleBrick(int& i, int argc, char** argv) { std::string mortarHex = argv[++i]; int brickW = 64, brickH = 24, mortarPx = 4; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { brickW = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { brickH = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { mortarPx = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, brickW); + parseOptInt(i, argc, argv, brickH); + parseOptInt(i, argc, argv, mortarPx); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || brickW < 4 || brickW > 4096 || brickH < 4 || brickH > 4096 || @@ -1496,18 +1391,10 @@ int handleWood(int& i, int argc, char** argv) { int spacing = 12; // average grain spacing in px uint32_t seed = 1; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { spacing = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, spacing); + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || spacing < 2 || spacing > 256) { std::fprintf(stderr, @@ -1621,18 +1508,10 @@ int handleGrass(int& i, int argc, char** argv) { float density = 0.15f; uint32_t seed = 1; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { density = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptFloat(i, argc, argv, density); + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || density < 0.0f || density > 1.0f) { std::fprintf(stderr, @@ -1716,15 +1595,9 @@ int handleFabric(int& i, int argc, char** argv) { std::string weftHex = argv[++i]; int threadPx = 4; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { threadPx = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, threadPx); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || threadPx < 2 || threadPx > 256) { std::fprintf(stderr, @@ -1800,18 +1673,10 @@ int handleTile(int& i, int argc, char** argv) { int tilePx = 32; int groutPx = 2; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { tilePx = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { groutPx = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, tilePx); + parseOptInt(i, argc, argv, groutPx); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || tilePx < 4 || tilePx > 1024 || groutPx < 0 || groutPx > tilePx / 2) { @@ -1894,18 +1759,10 @@ int handleBark(int& i, int argc, char** argv) { uint32_t seed = 1; float density = 0.04f; // fraction of columns that become cracks int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { density = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptFloat(i, argc, argv, density); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || density < 0.0f || density > 0.5f) { std::fprintf(stderr, @@ -2005,18 +1862,10 @@ int handleClouds(int& i, int argc, char** argv) { uint32_t seed = 1; float coverage = 0.5f; // 0=clear sky, 1=overcast int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { coverage = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptFloat(i, argc, argv, coverage); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || coverage < 0.0f || coverage > 1.0f) { std::fprintf(stderr, @@ -2106,18 +1955,10 @@ int handleStars(int& i, int argc, char** argv) { uint32_t seed = 1; float density = 0.005f; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { density = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptFloat(i, argc, argv, density); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || density < 0.0f || density > 1.0f) { std::fprintf(stderr, @@ -2195,18 +2036,10 @@ int handleVines(int& i, int argc, char** argv) { uint32_t seed = 1; int vineCount = 8; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { vineCount = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, vineCount); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || vineCount < 0 || vineCount > 256) { std::fprintf(stderr, @@ -2291,18 +2124,10 @@ int handleMosaic(int& i, int argc, char** argv) { int tilePx = 16; uint32_t seed = 1; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { tilePx = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, tilePx); + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || tilePx < 4 || tilePx > 256) { std::fprintf(stderr, @@ -2382,18 +2207,10 @@ int handleRust(int& i, int argc, char** argv) { uint32_t seed = 1; float coverage = 0.4f; // 0=clean metal, 1=fully oxidized int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { coverage = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptFloat(i, argc, argv, coverage); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || coverage < 0.0f || coverage > 1.0f) { std::fprintf(stderr, @@ -2486,18 +2303,10 @@ int handleCircuit(int& i, int argc, char** argv) { uint32_t seed = 1; int traceCount = 24; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { traceCount = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, traceCount); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || traceCount < 0 || traceCount > 1024) { std::fprintf(stderr, @@ -2593,18 +2402,10 @@ int handleCoral(int& i, int argc, char** argv) { uint32_t seed = 1; int branchCount = 12; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { branchCount = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, branchCount); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || branchCount < 0 || branchCount > 1024) { std::fprintf(stderr, @@ -2711,15 +2512,9 @@ int handleFlame(int& i, int argc, char** argv) { std::string hotHex = argv[++i]; uint32_t seed = 1; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192) { std::fprintf(stderr, "gen-texture-flame: invalid dims (W/H 1..8192)\n"); @@ -2803,15 +2598,9 @@ int handleTartan(int& i, int argc, char** argv) { std::string cHex = argv[++i]; int bandPx = 32; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bandPx = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, bandPx); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || bandPx < 4 || bandPx > 256) { std::fprintf(stderr, @@ -2892,15 +2681,9 @@ int handleArgyle(int& i, int argc, char** argv) { std::string stitchHex = argv[++i]; int cellPx = 64; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cellPx = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, cellPx); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || cellPx < 8 || cellPx > 512) { std::fprintf(stderr, @@ -2987,21 +2770,11 @@ int handleHerringbone(int& i, int argc, char** argv) { int lineSpacing = 12; // distance between adjacent lines along x int lineWidth = 4; // line thickness in shifted-x coords int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stripHeight = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { lineSpacing = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { lineWidth = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, stripHeight); + parseOptInt(i, argc, argv, lineSpacing); + parseOptInt(i, argc, argv, lineWidth); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || stripHeight < 4 || stripHeight > 256 || lineSpacing < 4 || lineSpacing > 256 || @@ -3073,18 +2846,10 @@ int handleScales(int& i, int argc, char** argv) { int cellW = 24; int cellH = 16; // shorter than wide for natural overlap int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cellW = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cellH = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, cellW); + parseOptInt(i, argc, argv, cellH); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || cellW < 4 || cellW > 256 || cellH < 4 || cellH > 256) { @@ -3173,15 +2938,9 @@ int handleStainedGlass(int& i, int argc, char** argv) { std::string cHex = argv[++i]; int cellCount = 32; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cellCount = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, cellCount); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || cellCount < 4 || cellCount > 1024) { std::fprintf(stderr, @@ -3291,21 +3050,11 @@ int handleShingles(int& i, int argc, char** argv) { int shadowH = 4; // shadow band thickness at top of each row int seamW = 1; // vertical seam width between shingles int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { shingleW = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { shingleH = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { shadowH = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, shingleW); + parseOptInt(i, argc, argv, shingleH); + parseOptInt(i, argc, argv, shadowH); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || shingleW < 4 || shingleW > 512 || shingleH < 4 || shingleH > 512 || @@ -3379,18 +3128,10 @@ int handleFrost(int& i, int argc, char** argv) { int seedCount = 80; int rayLen = 18; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seedCount = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { rayLen = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, seedCount); + parseOptInt(i, argc, argv, rayLen); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || seedCount < 1 || seedCount > 8192 || rayLen < 2 || rayLen > 256) { @@ -3498,18 +3239,10 @@ int handleParquet(int& i, int argc, char** argv) { int cellSize = 32; // cell side = 2N; each plank is N wide int gapW = 1; // gap line thickness between planks int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cellSize = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { gapW = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, cellSize); + parseOptInt(i, argc, argv, gapW); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || cellSize < 8 || cellSize > 512 || gapW < 0 || gapW * 4 >= cellSize) { @@ -3604,24 +3337,12 @@ int handleBubbles(int& i, int argc, char** argv) { int maxR = 24; int rimW = 2; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { bubbleCount = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { minR = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { maxR = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { rimW = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, bubbleCount); + parseOptInt(i, argc, argv, minR); + parseOptInt(i, argc, argv, maxR); + parseOptInt(i, argc, argv, rimW); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || bubbleCount < 1 || bubbleCount > 4096 || minR < 1 || maxR < minR || maxR > 1024 || @@ -3721,18 +3442,10 @@ int handleSpiderWeb(int& i, int argc, char** argv) { int spokes = 8; int rings = 5; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { spokes = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { rings = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, spokes); + parseOptInt(i, argc, argv, rings); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || spokes < 3 || spokes > 64 || rings < 1 || rings > 32) { @@ -3823,18 +3536,10 @@ int handleGingham(int& i, int argc, char** argv) { int stripeSpacing = 16; int stripeWidth = 8; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stripeSpacing = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stripeWidth = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, stripeSpacing); + parseOptInt(i, argc, argv, stripeWidth); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || stripeSpacing < 4 || stripeSpacing > 256 || stripeWidth < 1 || stripeWidth >= stripeSpacing) { @@ -3900,18 +3605,10 @@ int handleLattice(int& i, int argc, char** argv) { int lineSpacing = 24; int lineWidth = 3; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { lineSpacing = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { lineWidth = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, lineSpacing); + parseOptInt(i, argc, argv, lineWidth); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || lineSpacing < 4 || lineSpacing > 256 || lineWidth < 1 || lineWidth >= lineSpacing) { @@ -3973,15 +3670,9 @@ int handleHoneycomb(int& i, int argc, char** argv) { std::string borderHex = argv[++i]; int hexSide = 16; // hex side length in pixels int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { hexSide = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, hexSide); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || hexSide < 4 || hexSide > 256) { std::fprintf(stderr, @@ -4081,18 +3772,10 @@ int handleCracked(int& i, int argc, char** argv) { int seedCount = 12; int maxLength = 40; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seedCount = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { maxLength = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, seedCount); + parseOptInt(i, argc, argv, maxLength); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || seedCount < 1 || seedCount > 4096 || maxLength < 4 || maxLength > 1024) { @@ -4194,15 +3877,9 @@ int handleRunes(int& i, int argc, char** argv) { std::string runeHex = argv[++i]; int gridSpacing = 64; // rune slot size int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { gridSpacing = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, gridSpacing); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || gridSpacing < 16 || gridSpacing > 512) { std::fprintf(stderr, @@ -4313,18 +3990,10 @@ int handleLeopard(int& i, int argc, char** argv) { int spotCount = 60; int spotRadius = 8; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { spotCount = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { spotRadius = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, spotCount); + parseOptInt(i, argc, argv, spotRadius); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || spotCount < 1 || spotCount > 4096 || spotRadius < 2 || spotRadius > 256) { @@ -4432,21 +4101,11 @@ int handleZebra(int& i, int argc, char** argv) { int amplitude = 8; // sine-wave amplitude (px) int wavelength = 80; // x-period of the sine wave (px) int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stripePeriod = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { amplitude = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { wavelength = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, stripePeriod); + parseOptInt(i, argc, argv, amplitude); + parseOptInt(i, argc, argv, wavelength); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || stripePeriod < 4 || stripePeriod > 256 || amplitude < 0 || amplitude > 128 || @@ -4514,21 +4173,11 @@ int handleKnit(int& i, int argc, char** argv) { int cellH = 12; int strokeWidth = 2; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cellW = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cellH = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { strokeWidth = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, cellW); + parseOptInt(i, argc, argv, cellH); + parseOptInt(i, argc, argv, strokeWidth); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || cellW < 4 || cellW > 256 || cellH < 4 || cellH > 256 || @@ -4600,21 +4249,11 @@ int handleMoss(int& i, int argc, char** argv) { int density = 70; // 0..100 chance of spot per cell uint32_t seed = 1; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stride = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { density = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, stride); + parseOptInt(i, argc, argv, density); + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || stride < 4 || stride > 1024 || density < 0 || density > 100) { @@ -4709,18 +4348,10 @@ int handleStuds(int& i, int argc, char** argv) { int stride = 24; int studR = 7; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { stride = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { studR = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, stride); + parseOptInt(i, argc, argv, studR); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || stride < 4 || stride > 1024 || studR < 1 || studR * 2 >= stride) { @@ -4796,18 +4427,10 @@ int handleStarburst(int& i, int argc, char** argv) { int rayCount = 12; float beamWidth = 0.18f; // radians half-width of each ray int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { rayCount = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { beamWidth = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, rayCount); + parseOptFloat(i, argc, argv, beamWidth); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || rayCount < 2 || rayCount > 256 || beamWidth <= 0 || beamWidth >= 3.14f) { @@ -4891,15 +4514,9 @@ int handleCaustics(int& i, int argc, char** argv) { std::string hiHex = argv[++i]; int period = 24; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { period = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, period); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || period < 4 || period > 1024) { std::fprintf(stderr, @@ -4970,18 +4587,10 @@ int handleRope(int& i, int argc, char** argv) { int period = 24; int strandW = 8; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { period = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { strandW = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, period); + parseOptInt(i, argc, argv, strandW); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || period < 4 || period > 1024 || strandW < 2 || strandW > W) { @@ -5060,20 +4669,14 @@ int handleCorrugated(int& i, int argc, char** argv) { int period = 16; char dir = 'v'; // 'v' = vertical ridges, 'h' = horizontal int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { period = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, period); if (i + 1 < argc && argv[i + 1][0] != '-') { const char* a = argv[++i]; if (a[0] == 'h' || a[0] == 'H') dir = 'h'; else if (a[0] == 'v' || a[0] == 'V') dir = 'v'; } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || period < 2 || period > 1024) { std::fprintf(stderr, @@ -5132,21 +4735,11 @@ int handlePlanks(int& i, int argc, char** argv) { int grainsPerPlank = 5; uint32_t seed = 1; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { plankH = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { grainsPerPlank = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { seed = static_cast(std::stoul(argv[++i])); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, plankH); + parseOptInt(i, argc, argv, grainsPerPlank); + parseOptUint(i, argc, argv, seed); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || plankH < 4 || plankH > 256 || grainsPerPlank < 0 || grainsPerPlank > 64) { @@ -5244,24 +4837,12 @@ int handleChainmail(int& i, int argc, char** argv) { int ringR = 5; float strokeW = 1.5f; int W = 256, H = 256; - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cellW = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { cellH = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { ringR = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { strokeW = std::stof(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { W = std::stoi(argv[++i]); } catch (...) {} - } - if (i + 1 < argc && argv[i + 1][0] != '-') { - try { H = std::stoi(argv[++i]); } catch (...) {} - } + parseOptInt(i, argc, argv, cellW); + parseOptInt(i, argc, argv, cellH); + parseOptInt(i, argc, argv, ringR); + parseOptFloat(i, argc, argv, strokeW); + parseOptInt(i, argc, argv, W); + parseOptInt(i, argc, argv, H); if (W < 1 || H < 1 || W > 8192 || H > 8192 || cellW < 4 || cellW > 256 || cellH < 4 || cellH > 256 ||