13#include "absl/status/status.h"
14#include "absl/status/statusor.h"
15#include "absl/strings/str_cat.h"
16#include "absl/strings/str_format.h"
17#include "absl/strings/str_join.h"
18#include "imgui/imgui.h"
19#include "imgui/misc/cpp/imgui_stdlib.h"
60using ImGui::InputText;
79 [
this](uint16_t sheet,
const std::string& label) {
84 [
this](
const std::string& csv_text) -> absl::StatusOr<int> {
102 [
this] {
return Redo(); });
108 [
this](
const std::vector<size_t>& targets,
115 "graphics.sheet_browser_v2");
117 [
this](
bool visible) {
120 workspace->
OpenWindow(
"graphics.sheet_browser_v2");
122 workspace->CloseWindow(
"graphics.sheet_browser_v2");
136 "Gfx Groups: blockset/roomset/spriteset selection syncs with the "
138 "editor for this ROM session (each surface has its own preview "
161 scratch_view_->SetApplyValidator([
this](uint16_t sheet) -> absl::Status {
162 if (
const auto* current =
project()) {
164 if (policy.reserved_sheets.count(sheet))
165 return absl::FailedPreconditionError(
166 "The project reserves this graphics sheet");
168 return absl::OkStatus();
170 scratch_view_->SetExportValidator([
this](
const std::string& path) {
172 if (manager && manager->session_coordinator())
176 return absl::FailedPreconditionError(
177 "BIN export cannot replace an open ROM");
178 return absl::OkStatus();
180 window_manager->RegisterWindowContent(
181 std::make_unique<GraphicsScratchWindow>([
this] {
187 window_manager->RegisterWindowContent(
188 std::make_unique<GraphicsSheetBrowserPanel>([
this]() {
194 window_manager->RegisterWindowContent(
195 std::make_unique<GraphicsPixelEditorPanel>([
this]() {
201 window_manager->RegisterWindowContent(
202 std::make_unique<GraphicsPaletteControlsPanel>([
this]() {
208 window_manager->RegisterWindowContent(
209 std::make_unique<GraphicsUsagePreviewPanel>([
this]() {
211 const auto* current_project =
project();
213 current_project !=
nullptr
220 window_manager->RegisterWindowContent(
221 std::make_unique<GraphicsLinkSpritePanel>([
this]() {
227 window_manager->RegisterWindowContent(
228 std::make_unique<GraphicsGfxGroupPanel>([
this]() {
235 window_manager->RegisterWindowContent(
236 std::make_unique<GraphicsPalettesetPanel>([
this]() {
242 window_manager->RegisterWindowContent(
243 std::make_unique<GraphicsPrototypeViewerPanel>(
246 window_manager->RegisterWindowContent(
247 std::make_unique<GraphicsPolyhedralPanel>([
this]() {
254 window_manager->RegisterWindowContent(
255 std::make_unique<GraphicsImageImportPanel>([
this]() {
271 if (
rom()->is_loaded()) {
279 LOG_INFO(
"GraphicsEditor",
"Initializing textures for %d graphics sheets",
282 int sheets_queued = 0;
284 if (!sheets[i].is_active() || !sheets[i].surface()) {
290 if (!sheets[i].texture()) {
293 if (sheets[i].palette().empty()) {
298 game_data()->palette_groups.dungeon_main.size() > 0) {
299 sheets[i].SetPaletteWithTransparent(
300 game_data()->palette_groups.dungeon_main.palette(0), 0);
302 }
else if (i >= 113 && i <= 127) {
305 game_data()->palette_groups.sprites_aux1.size() > 0) {
306 sheets[i].SetPaletteWithTransparent(
307 game_data()->palette_groups.sprites_aux1.palette(0), 0);
312 sheets[i].SetPaletteWithTransparent(
313 game_data()->palette_groups.hud.palette(0), 0);
324 LOG_INFO(
"GraphicsEditor",
"Queued texture creation for %d graphics sheets",
328 return absl::OkStatus();
336 sheet_opts.
tooltip = absl::StrFormat(
337 "Sheet %d (0x%02X) — use Command Palette to jump between sheets",
341 std::move(sheet_opts));
348 modified_opts.
tooltip = absl::StrFormat(
353 std::move(modified_opts));
368 {
"gfx.source_capture",
"Source mapping",
369 "Captured when opened; preview uses live pixels"});
373 {
"gfx.selected_tile",
"Source tile", target->label});
375 for (
size_t i = 0; i < target->palette.size(); ++i) {
378 colors += absl::StrFormat(
"%04X", target->palette[i].snes());
381 {
"gfx.raw_palette",
"Raw index colors (SNES)", colors});
385 {
"gfx.current_sheet_revision",
"Current sheet revision",
396 if (editor_manager ==
nullptr || snapshot ==
nullptr ||
397 !editor_manager->IsCurrentProjectContextOwnedBySession(
399 return absl::FailedPreconditionError(
400 "Sheet labels need the project that owns this ROM to be active");
404 return absl::FailedPreconditionError(
405 "Open a .yaze project to store sheet labels");
411 editor_manager->MarkCurrentProjectDirty();
412 return absl::OkStatus();
415absl::StatusOr<GraphicsEditor::PreparedGraphicsSave>
418 return absl::FailedPreconditionError(
"ROM not loaded");
421 return absl::FailedPreconditionError(
"Game data not loaded");
426 return absl::FailedPreconditionError(
427 "Graphics sheets in memory belong to another open ROM. Switch back to "
428 "the ROM they were edited in, or reopen this ROM, before saving "
440 prepared.
refusals[sheet_id] =
"out of range";
442 prepared.
refusals[sheet_id] =
"reserved by the project";
445 prepared.
refusals[sheet_id] =
"2bpp, read-only";
446 }
else if (!sheets[sheet_id].is_active()) {
447 prepared.
refusals[sheet_id] =
"not loaded";
448 }
else if (std::any_of(sheets[sheet_id].vector().begin(),
449 sheets[sheet_id].vector().end(),
450 [](uint8_t index) {
return index > 7; })) {
452 prepared.
refusals[sheet_id] =
"uses colors above index 7";
458 const auto version_constants =
462 version_constants.kOverworldGfxPtr1);
465 version_constants.kOverworldGfxPtr2);
468 version_constants.kOverworldGfxPtr3);
474 return absl::OkStatus();
482 return absl::FailedPreconditionError(
483 "Commit or cancel the floating paste in Graphics before saving "
484 "(Enter to commit, Esc to cancel)");
486 return absl::FailedPreconditionError(
487 "Finish the pixel stroke before saving");
489 return absl::FailedPreconditionError(
"ROM not loaded");
494 LOG_INFO(
"GraphicsEditor",
"No modified sheets to save");
495 return absl::OkStatus();
502 std::vector<std::string> refused;
503 for (
const auto& [sheet_id, reason] : prepared.
refusals) {
504 refused.push_back(absl::StrFormat(
"0x%02X (%s)", sheet_id, reason));
506 return absl::FailedPreconditionError(absl::StrFormat(
507 "Graphics save refused for sheet(s) %s. Discard those edits to save "
509 absl::StrJoin(refused,
", ")));
512 LOG_INFO(
"GraphicsEditor",
"Saving %zu modified graphics sheets",
518 const std::vector<uint8_t> rom_snapshot =
rom_->
vector();
519 const bool rom_was_dirty =
rom_->
dirty();
520 auto restore = [&]() {
524 std::set<uint16_t> saved_sheets;
525 for (uint16_t sheet_id : prepared.
sheet_ids) {
526 const auto snes_data =
532 return absl::Status(result.status().code(),
533 absl::StrFormat(
"Graphics sheet 0x%02X not saved: %s",
534 sheet_id, result.status().message()));
536 LOG_INFO(
"GraphicsEditor",
"Saved sheet %02X (%zu bytes, %s) at 0x%06X",
537 sheet_id, result->new_stored_size,
542 saved_sheets.insert(sheet_id);
548 for (uint16_t sheet_id : prepared.
sheet_ids) {
550 *
rom_, sheet_id, sheets[sheet_id].vector(), prepared.
tables);
551 if (!verified.ok()) {
555 absl::StrFormat(
"Graphics save stopped; nothing was written: %s",
556 verified.message()));
562 return absl::OkStatus();
565absl::StatusOr<std::vector<GraphicsSavePlanEntry>>
568 std::vector<GraphicsSavePlanEntry> entries;
569 for (
const auto& [sheet_id, reason] : prepared.
refusals) {
573 entries.push_back(std::move(entry));
579 for (uint16_t sheet_id : prepared.
sheet_ids) {
582 const auto& pixels = sheets[sheet_id].vector();
587 entry.
refusal = std::string(result.status().message());
590 entry.
old_pc = result->old_pc;
591 entry.
new_pc = result->new_pc;
594 const absl::Status verified =
596 if (!verified.ok()) {
597 entry.
refusal = std::string(verified.message());
600 entries.push_back(std::move(entry));
602 std::sort(entries.begin(), entries.end(), [](
const auto& a,
const auto& b) {
603 return a.sheet_id < b.sheet_id;
612 return absl::FailedPreconditionError(
613 "Initialize Graphics before importing scratch assets");
622 scratch_view_->SetAssociatedPreview(std::move(label), std::move(callback));
639 return absl::OkStatus();
646 return absl::FailedPreconditionError(
"Finish the pixel stroke before Undo");
650 return absl::FailedPreconditionError(
651 "Finish the scratch stroke before Undo");
660 return absl::FailedPreconditionError(
"Finish the pixel stroke before Redo");
664 return absl::FailedPreconditionError(
665 "Finish the scratch stroke before Redo");
672 ImGui::TextWrapped(tr(
673 "No ROM loaded — CGX/SCR/COL/BIN and clipboard tools work without one. "
674 "Load a ROM when you want vanilla palette presets or to save graphics "
675 "back into a cartridge image."));
679 ImGui::TextColored(ImVec4(1.0f, 0.35f, 0.35f, 1.0f),
"%s",
681 if (ImGui::SmallButton(tr(
"Dismiss##prototype_import_feedback"))) {
693 constexpr ImGuiTableFlags kGfxEditFlags = ImGuiTableFlags_Reorderable |
694 ImGuiTableFlags_Resizable |
695 ImGuiTableFlags_SizingStretchSame;
700 ImGui::TableSetupColumn(
"Tilemaps and Objects (SCR, PNL, OBJ)",
701 ImGuiTableColumnFlags_WidthFixed);
726 ImGui::Image((ImTextureID)(intptr_t)
gfx_sheets_[i].texture(),
728 if ((i + 1) % 4 != 0) {
758 if (ImGui::Button(tr(
"Open CGX"))) {
766 if (ImGui::Button(tr(
"Copy CGX Path"))) {
770 if (ImGui::Button(tr(
"Load CGX Data"))) {
775 return absl::OkStatus();
787 return absl::OkStatus();
793 if (ImGui::Button(tr(
"Open SCR"))) {
803 if (ImGui::Button(tr(
"Load Scr Data"))) {
807 return absl::OkStatus();
815 absl::StrCat(
"[SCR draw] ",
status_.message());
816 return absl::OkStatus();
828 return absl::OkStatus();
836 if (ImGui::Button(tr(
"Open COL"))) {
845 auto col_file_palette_group_status =
847 if (col_file_palette_group_status.ok()) {
859 if (ImGui::Button(tr(
"Copy Col Path"))) {
863 if (
rom()->is_loaded()) {
867 IM_ARRAYSIZE(kPaletteGroupAddressesKeys));
875 return absl::OkStatus();
884 if (ImGui::Button(tr(
"Open OBJ"))) {
893 return absl::OkStatus();
902 if (ImGui::Button(tr(
"Open Tilemap"))) {
917 return absl::OkStatus();
926 if (ImGui::Button(tr(
"Open BIN"))) {
934 if (Button(tr(
"Copy File Path"))) {
941 if (Button(tr(
"Decompress BIN"))) {
943 return absl::InvalidArgumentError(
944 "Please select a file before decompressing.");
949 return absl::OkStatus();
954 if (Button(tr(
"Paste From Clipboard"))) {
955 const char* text = ImGui::GetClipboardText();
957 const auto clipboard_data =
958 std::vector<uint8_t>(text, text + strlen(text));
959 ImGui::MemFree((
void*)text);
969 if (Button(tr(
"Decompress Clipboard Data"))) {
973 status_ = absl::InvalidArgumentError(
974 "Please paste data into the clipboard before "
979 return absl::OkStatus();
984 if (Button(tr(
"Decompress Super Donkey Full"))) {
986 return absl::InvalidArgumentError(
987 "Please select `super_donkey_1.bin` before "
992 ImGui::SetItemTooltip(
993 tr(
"Requires `super_donkey_1.bin` to be imported under the "
994 "BIN import section."));
995 return absl::OkStatus();
999 std::string title =
"Memory Editor";
1005 return absl::OkStatus();
1031 return absl::OkStatus();
1038 std::stoi(offset,
nullptr, 16);
1051 return absl::FailedPreconditionError(
"GameData not available");
1066 std::stoi(offset,
nullptr, 16);
1093 return absl::OkStatus();
1126 return absl::FailedPreconditionError(
"Pixel editor is not open");
1129 return absl::OkStatus();
1134 return absl::FailedPreconditionError(
"Pixel editor is not open");
1137 return absl::OkStatus();
1142 return absl::FailedPreconditionError(
"Pixel editor is not open");
1145 return absl::OkStatus();
1163 return absl::FailedPreconditionError(
1164 "Graphics context belongs to a different ROM session");
1166 if (
context.targets.empty()) {
1167 return absl::InvalidArgumentError(
"Graphics context has no editable tiles");
1169 for (
const auto& target :
context.targets) {
1171 target.palette.size() != 8 ||
1175 return absl::InvalidArgumentError(
1176 "Graphics context needs loaded 3bpp sheets and eight indexed colors");
1180 return absl::FailedPreconditionError(
1181 "Commit or cancel the floating paste before opening another source");
1195 return absl::OkStatus();
1199 const std::vector<size_t>& targets,
1200 const std::array<uint8_t, 8>& permutation) {
1202 return absl::FailedPreconditionError(
"Finish the pixel stroke first");
1206 return absl::OkStatus();
1210 const std::string& label,
1211 double duration_secs) {
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
absl::Status LoadFromFile(const std::string &filename, const LoadOptions &options=LoadOptions::Defaults())
void set_dirty(bool dirty)
const auto & vector() const
absl::Status LoadFromData(const std::vector< uint8_t > &data, const LoadOptions &options=LoadOptions::Defaults())
const std::string & hack_name() const
static RomSettings & Get()
uint32_t GetAddressOr(const std::string &key, uint32_t default_value) const
The EditorManager controls the main editor window and manages the various editor classes.
SessionCoordinator * session_coordinator()
EditorContext context() const
UndoManager undo_manager_
project::YazeProject * project() const
zelda3::GameData * game_data() const
EditorDependencies dependencies_
std::optional< GraphicsEditContext > source_context
std::optional< uint16_t > requested_sheet_tab
std::set< uint16_t > selected_sheets
void HighlightTile(uint16_t sheet_id, uint16_t tile_index, const std::string &label="", double duration_secs=3.0)
Highlight a tile in the current sheet for quick visual focus.
std::set< uint16_t > modified_sheets
uint16_t current_sheet_id
std::function< void()> on_before_sheet_selected
uint64_t source_context_revision
bool HasUnsavedChanges() const
Check if any sheets have unsaved changes.
zelda3::GameData * game_data
void SelectSheet(uint16_t sheet_id)
Select a sheet for editing.
void SelectSourceTarget(size_t index)
void ClearSourceContext()
const GraphicsEditTarget * SourceTarget() const
void SetTool(PixelTool tool)
Set the current editing tool.
void ClearModifiedSheets()
Clear modification tracking (after save)
void ClearPreviewPalettes()
void FinishPixelGesture()
usage_preview::LiveRoomProvider room_usage_provider_
absl::Status SaveScratchAssets()
std::vector< uint8_t > scr_data_
GraphicsEditorState state_
absl::Status Save() override
void HighlightTile(uint16_t sheet_id, uint16_t tile_index, const std::string &label="", double duration_secs=3.0)
uint64_t clipboard_offset_
absl::Status ReorderSourcePalette(const std::vector< size_t > &targets, const std::array< uint8_t, 8 > &permutation)
GfxGroupEditor::RoomsetUsageCallback roomset_graphics_usage_
void SetPixelTool(PixelTool tool)
gfx::PaletteGroup col_file_palette_group_
void SelectSheet(uint16_t sheet_id)
std::string col_file_path_
std::string cgx_file_path_
absl::Status DrawMemoryEditor()
absl::Status Load() override
std::unique_ptr< GfxGroupEditor > gfx_group_panel_
zelda3::GameData * game_data_
std::unique_ptr< PaletteControlsPanel > palette_controls_panel_
void Initialize() override
std::vector< uint8_t > decoded_cgx_
EditorContextSnapshot BuildContextSnapshot() const override
std::string scr_file_path_
absl::Status Copy() override
absl::Status DecompressSuperDonkey()
std::unique_ptr< GraphicsScratchView > scratch_view_
GfxGroupEditor::MainUsageCallback main_graphics_usage_
absl::Status EditProject(const std::function< void(project::YazeProject &)> &edit)
gfx::SnesPalette col_file_palette_
std::string col_file_name_
absl::Status DrawCgxImport()
std::vector< uint8_t > cgx_data_
std::unique_ptr< PixelEditorPanel > pixel_editor_panel_
absl::Status Redo() override
std::unique_ptr< PolyhedralEditorPanel > polyhedral_panel_
std::unique_ptr< PalettesetEditorPanel > paletteset_panel_
std::function< absl::Status(const Rom &, uint16_t, const std::vector< uint8_t > &, const zelda3::GfxSheetPointerTables &) verify_written_sheet_)
absl::Status Cut() override
std::string obj_file_path_
void DrawPrototypeViewer()
absl::Status DrawFileImport()
std::vector< uint8_t > import_data_
uint64_t current_palette_index_
absl::Status Paste() override
absl::StatusOr< std::vector< GraphicsSavePlanEntry > > PlanGraphicsSave()
Graphics save preflight: every dirty sheet written to a scratch copy of the ROM (placement,...
std::vector< SDL_Color > decoded_col_
absl::Status Undo() override
absl::Status DrawTilemapImport()
absl::StatusOr< PreparedGraphicsSave > PrepareGraphicsSave()
gfx::SnesPalette z3_rom_palette_
absl::Status Update() override
absl::Status OpenInContext(GraphicsEditContext context)
absl::Status DrawScrImport()
absl::Status ImportScratchBin(const std::string &path, int bpp, size_t offset, const gfx::SnesPalette &palette={})
std::string tilemap_file_path_
usage_preview::LiveOverworldProvider overworld_usage_provider_
std::vector< uint8_t > extra_cgx_data_
void SetScratchPreview(std::string label, ScratchPreviewCallback callback)
std::array< gfx::Bitmap, zelda3::kNumGfxSheets > gfx_sheets_
std::unique_ptr< ImageImportView > image_import_view_
gui::Canvas import_canvas_
std::vector< uint8_t > decoded_scr_data_
std::string cgx_file_name_
std::unique_ptr< LinkSpritePanel > link_sprite_panel_
absl::Status DrawObjImport()
std::string prototype_import_feedback_
absl::Status DrawClipboardImport()
uint64_t num_sheets_to_load_
absl::Status DecompressImportData(int size)
void ContributeStatus(StatusBar *status_bar) override
std::unique_ptr< UsagePreviewView > usage_preview_view_
absl::Status DrawExperimentalFeatures()
absl::Status DrawPaletteControls()
std::unique_ptr< SheetBrowserPanel > sheet_browser_panel_
std::string scr_file_name_
absl::Status CheckBackingFileAvailable(const std::string &filepath, std::optional< size_t > excluded_session_id=std::nullopt) const
static bool PathsReferToSameBackingFile(const std::string &lhs, const std::string &rhs)
A session-aware status bar displayed at the bottom of the application.
void SetSelection(int count, int width=0, int height=0)
Set selection information.
void SetCustomSegment(const std::string &key, const std::string &value)
Set a custom segment with key-value pair.
absl::Status Redo()
Redo the top action. Returns error if stack is empty.
absl::Status Undo()
Undo the top action. Returns error if stack is empty.
bool IsWindowOpen(size_t session_id, const std::string &base_window_id) const
bool OpenWindow(size_t session_id, const std::string &base_window_id)
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
GraphicsSheets & gfx_sheets()
Represents a bitmap image optimized for SNES ROM hacking.
void Create(int width, int height, int depth, std::span< uint8_t > data)
Create a bitmap with the given dimensions and data.
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap using SNES palette format.
RAII timer for automatic timing management.
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
CanvasConfig & GetConfig()
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
bool HasSheet(uint16_t sheet) const
True when the buffer holds all 4096 bytes of sheet.
uint64_t Revision(uint16_t sheet) const
Locates graphics sheets in the ROM and writes edited sheets back.
#define LOG_INFO(category, format,...)
#define BEGIN_TABLE(l, n, f)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
#define CLEAR_AND_RETURN_STATUS(status)
#define HOVER_HINT(string)
constexpr char kOverworldGfxPtr3[]
constexpr char kOverworldGfxPtr1[]
constexpr char kOverworldGfxPtr2[]
absl::StatusOr< zelda3::GfxSheetWritePolicy > BuildGfxSheetWritePolicy(const HackManifest &manifest)
void SetGraphicsSheetLabel(project::YazeProject &project, uint16_t sheet, const std::string &label)
int ImportSpritesetSheetLabels(project::YazeProject &project, const std::string &csv_text, bool overwrite)
int SyncArenaFromStore(GraphicsEditorState &state)
std::array< uint8_t, 8 > PalettePermutation
const std::string kSuperDonkeySprites[]
void AppendResolvedGraphicsContext(EditorContextSnapshot &snapshot, const zelda3::ResolvedGraphicsContext &context)
void AttachSheetStore(GraphicsEditorState &state, zelda3::GameData *game_data)
const std::string kSuperDonkeyTiles[]
void RefreshGraphicsPreviewPalettes(GraphicsEditorState &state)
PixelTool
Pixel editing tool types for the graphics editor.
std::function< absl::StatusOr< usage_preview::PreviewImage >( const GraphicsScratchAsset &)> ScratchPreviewCallback
absl::Status ApplyPalettePixelPermutation(GraphicsEditorState &state, UndoManager &history, const std::vector< size_t > &targets, const PalettePermutation &permutation)
absl::StatusOr< std::vector< uint8_t > > DecompressV2(const uint8_t *data, int offset, int size, int mode, size_t rom_size)
Decompresses a buffer of data using the LC_LZ2 algorithm.
constexpr int kNintendoMode1
absl::Status LoadScr(std::string_view filename, uint8_t input_value, std::vector< uint8_t > &map_data)
Load Scr file (screen data)
std::vector< SDL_Color > DecodeColFile(const std::string_view filename)
Decode color file.
constexpr int kTilesheetHeight
constexpr int kTilesheetWidth
absl::Status LoadCgx(uint8_t bpp, std::string_view filename, std::vector< uint8_t > &cgx_data, std::vector< uint8_t > &cgx_loaded, std::vector< uint8_t > &cgx_header)
Load Cgx file (graphical content)
constexpr const char * kPaletteGroupAddressesKeys[]
absl::Status DrawScrWithCgx(uint8_t bpp, std::vector< uint8_t > &map_bitmap_data, std::vector< uint8_t > &map_data, std::vector< uint8_t > &cgx_loaded)
Draw screen tilemap with graphical data.
constexpr int kTilesheetDepth
std::vector< uint8_t > SnesTo8bppSheet(std::span< const uint8_t > sheet, int bpp, int num_sheets)
std::vector< uint8_t > IndexedToSnesSheet(std::span< const uint8_t > sheet, int bpp, int num_sheets)
absl::StatusOr< PaletteGroup > CreatePaletteGroupFromColFile(std::vector< SnesColor > &palette_rows)
std::vector< SnesColor > GetColFileData(uint8_t *data)
bool InputHex(const char *label, uint64_t *data)
void SelectablePalettePipeline(uint64_t &palette_id, bool &refresh_graphics, gfx::SnesPalette &palette)
void BitmapCanvasPipeline(Canvas &canvas, gfx::Bitmap &bitmap, int width, int height, int tile_size, bool is_loaded, bool scrollbar, int canvas_id)
void TextWithSeparators(const absl::string_view &text)
absl::StatusOr< GfxSheetWriteResult > WriteGfxSheet(Rom &rom, uint16_t sheet_id, const std::vector< uint8_t > &snes_3bpp, const GfxSheetWritePolicy &policy, const GfxSheetPointerTables &tables)
Writes one edited 3bpp sheet to the ROM buffer.
constexpr uint32_t kNumGfxSheets
GfxSheetStorageKind GetGfxSheetStorageKind(uint16_t sheet_id)
#define RETURN_IF_ERROR(expr)
std::string semantic_owner
std::vector< EditorContextValue > metadata
WorkspaceWindowManager * window_manager
GfxGroupWorkspaceState * gfx_group_workspace
std::map< uint16_t, std::string > refusals
zelda3::GfxSheetPointerTables tables
std::vector< uint16_t > sheet_ids
zelda3::GfxSheetWritePolicy policy
zelda3::GfxSheetPlacement placement
Optional behavior for an interactive status bar segment.
PaletteGroup overworld_animated
PaletteGroup * get_group(const std::string &group_name)
Modern project structure with comprehensive settings consolidation.
core::HackManifest hack_manifest
gfx::PaletteGroupMap palette_groups
std::set< uint16_t > reserved_sheets
GraphicsSheetStore sheet_store