yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_render_commands.cc
Go to the documentation of this file.
2
3#include <fstream>
4#include <sstream>
5#include <string>
6#include <vector>
7
8#include "absl/strings/str_format.h"
11#include "rom/rom.h"
12#include "zelda3/game_data.h"
13
14namespace yaze {
15namespace cli {
16namespace handlers {
17
18namespace {
19
20// Parse overlays from a comma-separated string into RenderOverlay flags.
21uint32_t ParseOverlays(const std::string& s) {
22 if (s.empty())
25 std::istringstream ss(s);
26 std::string tok;
27 while (std::getline(ss, tok, ',')) {
28 tok.erase(0, tok.find_first_not_of(" \t"));
29 if (!tok.empty())
30 tok.erase(tok.find_last_not_of(" \t") + 1);
31 if (tok == "collision")
33 else if (tok == "sprites")
35 else if (tok == "objects")
37 else if (tok == "track")
39 else if (tok == "camera")
41 else if (tok == "grid")
43 else if (tok == "all")
45 }
46 return flags;
47}
48
49} // namespace
50
52 const resources::ArgumentParser& parser) {
53 return parser.RequireArgs({"room", "output"});
54}
55
57 Rom* rom, const resources::ArgumentParser& parser,
58 resources::OutputFormatter& formatter) {
59 // Parse --room (decimal or 0x-hex).
60 auto room_str = parser.GetString("room").value();
61 int room_id = 0;
62 try {
63 room_id = std::stoi(room_str, nullptr, 0);
64 } catch (...) {
65 return absl::InvalidArgumentError(
66 absl::StrFormat("Invalid room id: %s", room_str));
67 }
68
69 // Parse --output.
70 const std::string output_path = parser.GetString("output").value();
71
72 // Parse --overlays (optional, default none).
73 uint32_t overlay_flags = app::service::RenderOverlay::kNone;
74 if (auto ov = parser.GetString("overlays"); ov.has_value()) {
75 overlay_flags = ParseOverlays(ov.value());
76 }
77
78 // Parse --scale (optional, default 1.0, clamped 0.25–8.0).
79 float scale = 1.0f;
80 if (auto sc = parser.GetString("scale"); sc.has_value()) {
81 try {
82 scale = std::stof(sc.value());
83 if (scale < 0.25f)
84 scale = 0.25f;
85 if (scale > 8.0f)
86 scale = 8.0f;
87 } catch (...) {
88 return absl::InvalidArgumentError(
89 absl::StrFormat("Invalid scale value: %s", sc.value()));
90 }
91 }
92
93 // Load GameData (palette groups, tileset tables).
94 zelda3::GameData game_data;
95 auto gd_status = zelda3::LoadGameData(*rom, game_data);
96 if (!gd_status.ok()) {
97 return absl::InternalError(
98 absl::StrFormat("Failed to load game data: %s", gd_status.message()));
99 }
100
101 // Render.
102 app::service::RenderService render_service(rom, &game_data);
104 req.room_id = room_id;
105 req.overlay_flags = overlay_flags;
106 req.scale = scale;
107
108 auto result_or = render_service.RenderDungeonRoom(req);
109 if (!result_or.ok())
110 return result_or.status();
111 const auto& result = *result_or;
112
113 // Write PNG to disk.
114 std::ofstream out(output_path, std::ios::binary);
115 if (!out) {
116 return absl::InternalError(
117 absl::StrFormat("Cannot open output file: %s", output_path));
118 }
119 out.write(reinterpret_cast<const char*>(result.png_data.data()),
120 static_cast<std::streamsize>(result.png_data.size()));
121 if (!out) {
122 return absl::InternalError(
123 absl::StrFormat("Write failed for: %s", output_path));
124 }
125 out.close();
126
127 formatter.AddField("room_id", absl::StrFormat("0x%02X", room_id));
128 formatter.AddField("output", output_path);
129 formatter.AddField("width", result.width);
130 formatter.AddField("height", result.height);
131 formatter.AddField("size_bytes", static_cast<int>(result.png_data.size()));
132 return absl::OkStatus();
133}
134
135} // namespace handlers
136} // namespace cli
137} // namespace yaze
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:28
absl::StatusOr< RenderResult > RenderDungeonRoom(const RenderRequest &req)
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status ValidateArgs(const resources::ArgumentParser &parser) override
Validate command arguments.
Utility for parsing common CLI argument patterns.
std::optional< std::string > GetString(const std::string &name) const
Parse a named argument (e.g., –format=json or –format json)
absl::Status RequireArgs(const std::vector< std::string > &required) const
Validate that required arguments are present.
Utility for consistent output formatting across commands.
void AddField(const std::string &key, const std::string &value)
Add a key-value pair.
absl::Status LoadGameData(Rom &rom, GameData &data, const LoadOptions &options)
Loads all Zelda3-specific game data from a generic ROM.
Definition game_data.cc:123