yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
graphics_sheet_sync.cc
Go to the documentation of this file.
2
3#include <algorithm>
4
5#include "absl/strings/str_format.h"
8#include "util/macro.h"
9#include "zelda3/game_data.h"
11
12namespace yaze::editor {
13
14namespace {
15
17
18} // namespace
19
21 absl::Span<const uint8_t> before,
22 absl::Span<const uint8_t> after) {
23 SheetPixelDiff diff;
24 diff.sheet = sheet;
25 const size_t size = std::min(before.size(), after.size());
26 for (size_t i = 0; i < size; ++i) {
27 if (before[i] != after[i]) {
28 diff.offsets.push_back(static_cast<uint16_t>(i));
29 diff.before.push_back(before[i]);
30 diff.after.push_back(after[i]);
31 }
32 }
33 return diff;
34}
35
37 if (state.game_data != game_data) {
38 state.ClearSourceContext();
39 state.preview_palettes.clear();
40 }
41 state.game_data = game_data;
42 state.arena_revisions.fill(0);
43 if (game_data == nullptr) {
44 return;
45 }
46 for (uint16_t sheet = 0; sheet < state.arena_revisions.size(); ++sheet) {
47 state.arena_revisions[sheet] = game_data->sheet_store.Revision(sheet);
48 }
49}
50
52 if (state.game_data == nullptr ||
54 return nullptr;
55 }
56 return &state.game_data->sheet_store;
57}
58
59void RefreshArenaSheet(GraphicsEditorState& state, uint16_t sheet) {
60 auto* store = ActiveSheetStore(state);
61 if (store == nullptr || !store->HasSheet(sheet)) {
62 return;
63 }
64 auto& bitmap = gfx::Arena::Get().mutable_gfx_sheets()->at(sheet);
65 if (!bitmap.is_active() || bitmap.vector().size() != kSheetBytes) {
66 return; // not on screen; nothing to refresh
67 }
68 const auto pixels = store->Sheet(sheet);
69 if (!std::equal(pixels.begin(), pixels.end(), bitmap.vector().begin())) {
70 bitmap.set_data(std::vector<uint8_t>(pixels.begin(), pixels.end()));
72 }
73 state.arena_revisions[sheet] = store->Revision(sheet);
74}
75
76absl::Status CommitSheetPixels(GraphicsEditorState& state, uint16_t sheet,
77 absl::Span<const uint8_t> pixels) {
78 auto* store = ActiveSheetStore(state);
79 if (store == nullptr) {
80 return absl::FailedPreconditionError(
81 "Graphics for this ROM are not loaded, or another open ROM's sheets "
82 "are on screen");
83 }
84 const uint64_t revision = store->Revision(sheet);
85 if (absl::Status written = store->WriteSheet(sheet, pixels); !written.ok()) {
86 return written;
87 }
88 RefreshArenaSheet(state, sheet);
89 if (store->Revision(sheet) != revision) {
90 state.MarkSheetModified(sheet);
91 }
92 return absl::OkStatus();
93}
94
96 const SheetPixelDiff& diff, bool redo) {
97 auto* store = ActiveSheetStore(state);
98 if (store == nullptr || !store->HasSheet(diff.sheet)) {
99 return absl::FailedPreconditionError(absl::StrFormat(
100 "Sheet 0x%02X is not in this ROM's loaded graphics", diff.sheet));
101 }
102 const auto current = store->Sheet(diff.sheet);
103 std::vector<uint8_t> pixels(current.begin(), current.end());
104 const auto& values = redo ? diff.after : diff.before;
105 for (size_t i = 0; i < diff.offsets.size(); ++i) {
106 pixels[diff.offsets[i]] = values[i];
107 }
108 RETURN_IF_ERROR(CommitSheetPixels(state, diff.sheet, pixels));
109 // Undo and redo leave the sheet different from the ROM either way.
110 state.MarkSheetModified(diff.sheet);
111 return absl::OkStatus();
112}
113
115 auto* store = ActiveSheetStore(state);
116 if (store == nullptr) {
117 return 0;
118 }
119 int refreshed = 0;
120 for (uint16_t sheet = 0; sheet < state.arena_revisions.size(); ++sheet) {
121 if (store->Revision(sheet) != state.arena_revisions[sheet]) {
122 RefreshArenaSheet(state, sheet);
123 ++refreshed;
124 }
125 }
126 return refreshed;
127}
128
129} // namespace yaze::editor
Shared state between GraphicsEditor panel components.
void MarkSheetModified(uint16_t sheet_id)
Mark a sheet as modified for save tracking.
std::map< uint16_t, GraphicsPaletteSelection > preview_palettes
std::array< uint64_t, 223 > arena_revisions
const void * gfx_sheets_owner() const
Definition arena.h:216
auto mutable_gfx_sheets()
Get mutable reference to all graphics sheets.
Definition arena.h:206
void NotifySheetModified(int sheet_index)
Notify Arena that a graphics sheet has been modified.
Definition arena.cc:532
static Arena & Get()
Definition arena.cc:24
uint64_t Revision(uint16_t sheet) const
One ROM session's graphics sheet pixels, with a revision per sheet.
The Graphics editor's path for sheet pixel writes.
Editors are the view controllers for the application.
zelda3::GraphicsSheetStore * ActiveSheetStore(const GraphicsEditorState &state)
int SyncArenaFromStore(GraphicsEditorState &state)
absl::Status CommitSheetPixels(GraphicsEditorState &state, uint16_t sheet, absl::Span< const uint8_t > pixels)
void AttachSheetStore(GraphicsEditorState &state, zelda3::GameData *game_data)
void RefreshArenaSheet(GraphicsEditorState &state, uint16_t sheet)
absl::Status ApplySheetPixelDiff(GraphicsEditorState &state, const SheetPixelDiff &diff, bool redo)
SheetPixelDiff MakeSheetPixelDiff(uint16_t sheet, absl::Span< const uint8_t > before, absl::Span< const uint8_t > after)
The pixels that differ between two 4096-byte sheets.
#define RETURN_IF_ERROR(expr)
Definition snes.cc:22
The pixels one undo step changes in one sheet.
std::vector< uint16_t > offsets
std::vector< uint8_t > before