From 0a1ba6f94b0c14b03d6c0a1fa0c270db82582093 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sat, 9 May 2026 07:38:36 -0700 Subject: [PATCH] refactor(editor): extract --info-{zone,project}-audio into cli_info_audio.cpp Moves the two audio-config audit handlers (--info-zone-audio, --info-project-audio) out of main.cpp into a new cli_info_audio.{hpp,cpp} module. Both surface the music / day-ambience / night-ambience / volume settings stored in zone.json so designers can spot zones still missing audio assignment before a release pass. main.cpp shrinks by 127 lines (7,053 to 6,926). Drops the dead `label` lambda inside info-project-audio that the unused-but-set-variable warning had been flagging. Both --json output modes preserved. --- CMakeLists.txt | 1 + tools/editor/cli_info_audio.cpp | 163 ++++++++++++++++++++++++++++++++ tools/editor/cli_info_audio.hpp | 23 +++++ tools/editor/main.cpp | 136 +------------------------- 4 files changed, 191 insertions(+), 132 deletions(-) create mode 100644 tools/editor/cli_info_audio.cpp create mode 100644 tools/editor/cli_info_audio.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b2d76474..37659250 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1334,6 +1334,7 @@ add_executable(wowee_editor tools/editor/cli_info_extents.cpp tools/editor/cli_info_water.cpp tools/editor/cli_info_density.cpp + tools/editor/cli_info_audio.cpp tools/editor/editor_app.cpp tools/editor/editor_camera.cpp tools/editor/editor_viewport.cpp diff --git a/tools/editor/cli_info_audio.cpp b/tools/editor/cli_info_audio.cpp new file mode 100644 index 00000000..4b63d324 --- /dev/null +++ b/tools/editor/cli_info_audio.cpp @@ -0,0 +1,163 @@ +#include "cli_info_audio.hpp" + +#include "zone_manifest.hpp" +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace wowee { +namespace editor { +namespace cli { + +namespace { + +int handleInfoZoneAudio(int& i, int argc, char** argv) { + // Print the audio configuration stored in zone.json: + // music track, day/night ambience, volume sliders. + // Useful for spot-checking that the zone has been wired + // up to the right audio assets before bake/export. + std::string zoneDir = argv[++i]; + bool jsonOut = (i + 1 < argc && + std::strcmp(argv[i + 1], "--json") == 0); + if (jsonOut) i++; + namespace fs = std::filesystem; + std::string manifestPath = zoneDir + "/zone.json"; + if (!fs::exists(manifestPath)) { + std::fprintf(stderr, + "info-zone-audio: %s has no zone.json\n", zoneDir.c_str()); + return 1; + } + wowee::editor::ZoneManifest zm; + if (!zm.load(manifestPath)) { + std::fprintf(stderr, + "info-zone-audio: failed to parse %s\n", + manifestPath.c_str()); + return 1; + } + if (jsonOut) { + nlohmann::json j; + j["zone"] = zoneDir; + j["music"] = zm.musicTrack; + j["ambienceDay"] = zm.ambienceDay; + j["ambienceNight"] = zm.ambienceNight; + j["musicVolume"] = zm.musicVolume; + j["ambienceVolume"] = zm.ambienceVolume; + std::printf("%s\n", j.dump(2).c_str()); + return 0; + } + std::printf("Zone audio: %s\n", zoneDir.c_str()); + std::printf(" music : %s\n", + zm.musicTrack.empty() ? "(none)" : zm.musicTrack.c_str()); + std::printf(" ambience day : %s\n", + zm.ambienceDay.empty() ? "(none)" : zm.ambienceDay.c_str()); + std::printf(" ambience night: %s\n", + zm.ambienceNight.empty() ? "(none)" : zm.ambienceNight.c_str()); + std::printf(" music vol : %.2f\n", zm.musicVolume); + std::printf(" ambience vol : %.2f\n", zm.ambienceVolume); + return 0; +} + +int handleInfoProjectAudio(int& i, int argc, char** argv) { + // Project-wide audio rollup. Walks every zone in + // , reads the audio fields out of zone.json, + // emits a table showing which zones have music/ambience + // configured. Useful for spotting zones still missing + // audio assignment before a release pass. + std::string projectDir = argv[++i]; + bool jsonOut = (i + 1 < argc && + std::strcmp(argv[i + 1], "--json") == 0); + if (jsonOut) i++; + namespace fs = std::filesystem; + if (!fs::exists(projectDir) || !fs::is_directory(projectDir)) { + std::fprintf(stderr, + "info-project-audio: %s is not a directory\n", + projectDir.c_str()); + return 1; + } + std::vector zones; + for (const auto& entry : fs::directory_iterator(projectDir)) { + if (!entry.is_directory()) continue; + if (!fs::exists(entry.path() / "zone.json")) continue; + zones.push_back(entry.path().string()); + } + std::sort(zones.begin(), zones.end()); + struct Row { + std::string name; + std::string music; + std::string ambDay; + std::string ambNight; + float musicVol, ambVol; + }; + std::vector rows; + int withMusic = 0, withAmbience = 0; + for (const auto& zoneDir : zones) { + wowee::editor::ZoneManifest zm; + if (!zm.load(zoneDir + "/zone.json")) continue; + Row r; + r.name = fs::path(zoneDir).filename().string(); + r.music = zm.musicTrack; + r.ambDay = zm.ambienceDay; + r.ambNight = zm.ambienceNight; + r.musicVol = zm.musicVolume; + r.ambVol = zm.ambienceVolume; + if (!r.music.empty()) withMusic++; + if (!r.ambDay.empty() || !r.ambNight.empty()) withAmbience++; + rows.push_back(r); + } + if (jsonOut) { + nlohmann::json j; + j["project"] = projectDir; + j["zoneCount"] = zones.size(); + j["withMusic"] = withMusic; + j["withAmbience"] = withAmbience; + nlohmann::json arr = nlohmann::json::array(); + for (const auto& r : rows) { + arr.push_back({{"name", r.name}, + {"music", r.music}, + {"ambienceDay", r.ambDay}, + {"ambienceNight", r.ambNight}, + {"musicVolume", r.musicVol}, + {"ambienceVolume", r.ambVol}}); + } + j["zones"] = arr; + std::printf("%s\n", j.dump(2).c_str()); + return 0; + } + std::printf("Project audio: %s\n", projectDir.c_str()); + std::printf(" zones : %zu\n", zones.size()); + std::printf(" with music : %d\n", withMusic); + std::printf(" with ambience : %d\n", withAmbience); + std::printf("\n zone music? ambience? m-vol a-vol\n"); + for (const auto& r : rows) { + std::string ambLabel = !r.ambDay.empty() ? r.ambDay : + !r.ambNight.empty() ? r.ambNight : ""; + std::printf(" %-22s %-6s %-9s %5.2f %5.2f\n", + r.name.substr(0, 22).c_str(), + r.music.empty() ? "no" : "yes", + ambLabel.empty() ? "no" : "yes", + r.musicVol, r.ambVol); + } + return 0; +} + +} // namespace + +bool handleInfoAudio(int& i, int argc, char** argv, int& outRc) { + if (std::strcmp(argv[i], "--info-zone-audio") == 0 && i + 1 < argc) { + outRc = handleInfoZoneAudio(i, argc, argv); return true; + } + if (std::strcmp(argv[i], "--info-project-audio") == 0 && i + 1 < argc) { + outRc = handleInfoProjectAudio(i, argc, argv); return true; + } + return false; +} + +} // namespace cli +} // namespace editor +} // namespace wowee diff --git a/tools/editor/cli_info_audio.hpp b/tools/editor/cli_info_audio.hpp new file mode 100644 index 00000000..e5298743 --- /dev/null +++ b/tools/editor/cli_info_audio.hpp @@ -0,0 +1,23 @@ +#pragma once + +namespace wowee { +namespace editor { +namespace cli { + +// Dispatch the audio-config audit handlers — print the +// music / day-ambience / night-ambience / volume settings +// stored in zone.json. Useful for spot-checking that a zone +// is wired up to the right audio assets, and for catching +// zones still missing audio assignment before a release pass. +// --info-zone-audio one zone's audio config +// --info-project-audio table across every zone in a project +// +// Both support an optional trailing `--json` flag for +// machine-readable reports. +// +// Returns true if matched; outRc holds the exit code. +bool handleInfoAudio(int& i, int argc, char** argv, int& outRc); + +} // namespace cli +} // namespace editor +} // namespace wowee diff --git a/tools/editor/main.cpp b/tools/editor/main.cpp index f141ca17..e81e301b 100644 --- a/tools/editor/main.cpp +++ b/tools/editor/main.cpp @@ -35,6 +35,7 @@ #include "cli_info_extents.hpp" #include "cli_info_water.hpp" #include "cli_info_density.hpp" +#include "cli_info_audio.hpp" #include "content_pack.hpp" #include "npc_spawner.hpp" #include "object_placer.hpp" @@ -473,6 +474,9 @@ int main(int argc, char* argv[]) { if (wowee::editor::cli::handleInfoDensity(i, argc, argv, outRc)) { return outRc; } + if (wowee::editor::cli::handleInfoAudio(i, argc, argv, outRc)) { + return outRc; + } } if (std::strcmp(argv[i], "--data") == 0 && i + 1 < argc) { dataPath = argv[++i]; @@ -2953,138 +2957,6 @@ int main(int argc, char* argv[]) { std::printf(" produced : %d\n", produced); std::printf(" failed : %d\n", failed); return failed == 0 ? 0 : 1; - } else if (std::strcmp(argv[i], "--info-zone-audio") == 0 && i + 1 < argc) { - // Print the audio configuration stored in zone.json: - // music track, day/night ambience, volume sliders. - // Useful for spot-checking that the zone has been wired - // up to the right audio assets before bake/export. - std::string zoneDir = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; - namespace fs = std::filesystem; - std::string manifestPath = zoneDir + "/zone.json"; - if (!fs::exists(manifestPath)) { - std::fprintf(stderr, - "info-zone-audio: %s has no zone.json\n", zoneDir.c_str()); - return 1; - } - wowee::editor::ZoneManifest zm; - if (!zm.load(manifestPath)) { - std::fprintf(stderr, - "info-zone-audio: failed to parse %s\n", - manifestPath.c_str()); - return 1; - } - if (jsonOut) { - nlohmann::json j; - j["zone"] = zoneDir; - j["music"] = zm.musicTrack; - j["ambienceDay"] = zm.ambienceDay; - j["ambienceNight"] = zm.ambienceNight; - j["musicVolume"] = zm.musicVolume; - j["ambienceVolume"] = zm.ambienceVolume; - std::printf("%s\n", j.dump(2).c_str()); - return 0; - } - std::printf("Zone audio: %s\n", zoneDir.c_str()); - std::printf(" music : %s\n", - zm.musicTrack.empty() ? "(none)" : zm.musicTrack.c_str()); - std::printf(" ambience day : %s\n", - zm.ambienceDay.empty() ? "(none)" : zm.ambienceDay.c_str()); - std::printf(" ambience night: %s\n", - zm.ambienceNight.empty() ? "(none)" : zm.ambienceNight.c_str()); - std::printf(" music vol : %.2f\n", zm.musicVolume); - std::printf(" ambience vol : %.2f\n", zm.ambienceVolume); - return 0; - } else if (std::strcmp(argv[i], "--info-project-audio") == 0 && i + 1 < argc) { - // Project-wide audio rollup. Walks every zone in - // , reads the audio fields out of zone.json, - // emits a table showing which zones have music/ambience - // configured. Useful for spotting zones still missing - // audio assignment before a release pass. - std::string projectDir = argv[++i]; - bool jsonOut = (i + 1 < argc && - std::strcmp(argv[i + 1], "--json") == 0); - if (jsonOut) i++; - namespace fs = std::filesystem; - if (!fs::exists(projectDir) || !fs::is_directory(projectDir)) { - std::fprintf(stderr, - "info-project-audio: %s is not a directory\n", - projectDir.c_str()); - return 1; - } - std::vector zones; - for (const auto& entry : fs::directory_iterator(projectDir)) { - if (!entry.is_directory()) continue; - if (!fs::exists(entry.path() / "zone.json")) continue; - zones.push_back(entry.path().string()); - } - std::sort(zones.begin(), zones.end()); - struct Row { - std::string name; - std::string music; - std::string ambDay; - std::string ambNight; - float musicVol, ambVol; - }; - std::vector rows; - int withMusic = 0, withAmbience = 0; - for (const auto& zoneDir : zones) { - wowee::editor::ZoneManifest zm; - if (!zm.load(zoneDir + "/zone.json")) continue; - Row r; - r.name = fs::path(zoneDir).filename().string(); - r.music = zm.musicTrack; - r.ambDay = zm.ambienceDay; - r.ambNight = zm.ambienceNight; - r.musicVol = zm.musicVolume; - r.ambVol = zm.ambienceVolume; - if (!r.music.empty()) withMusic++; - if (!r.ambDay.empty() || !r.ambNight.empty()) withAmbience++; - rows.push_back(r); - } - if (jsonOut) { - nlohmann::json j; - j["project"] = projectDir; - j["zoneCount"] = zones.size(); - j["withMusic"] = withMusic; - j["withAmbience"] = withAmbience; - nlohmann::json arr = nlohmann::json::array(); - for (const auto& r : rows) { - arr.push_back({{"name", r.name}, - {"music", r.music}, - {"ambienceDay", r.ambDay}, - {"ambienceNight", r.ambNight}, - {"musicVolume", r.musicVol}, - {"ambienceVolume", r.ambVol}}); - } - j["zones"] = arr; - std::printf("%s\n", j.dump(2).c_str()); - return 0; - } - std::printf("Project audio: %s\n", projectDir.c_str()); - std::printf(" zones : %zu\n", zones.size()); - std::printf(" with music : %d\n", withMusic); - std::printf(" with ambience : %d\n", withAmbience); - std::printf("\n zone music? ambience? m-vol a-vol\n"); - auto label = [](const std::string& s) { - if (s.empty()) return "(none)"; - auto sl = s.rfind('\\'); - if (sl == std::string::npos) sl = s.rfind('/'); - return sl == std::string::npos ? s.c_str() - : s.c_str() + sl + 1; - }; - for (const auto& r : rows) { - std::string ambLabel = !r.ambDay.empty() ? r.ambDay : - !r.ambNight.empty() ? r.ambNight : ""; - std::printf(" %-22s %-6s %-9s %5.2f %5.2f\n", - r.name.substr(0, 22).c_str(), - r.music.empty() ? "no" : "yes", - ambLabel.empty() ? "no" : "yes", - r.musicVol, r.ambVol); - } - return 0; } else if (std::strcmp(argv[i], "--set-item") == 0 && i + 2 < argc) { // Edit fields on an existing item in place. Lookup is by // id by default; '#N' for index lookup. Only specified