yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
tile16_editor.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_TILE16EDITOR_H
2#define YAZE_APP_EDITOR_TILE16EDITOR_H
3
4#include <array>
5#include <cstdint>
6#include <functional>
7#include <string>
8#include <utility>
9#include <vector>
10
11#include "absl/status/status.h"
15#include "app/gfx/core/bitmap.h"
17#include "app/gui/core/input.h"
19#include "imgui/imgui.h"
20#include "rom/rom.h"
21#include "util/notify.h"
22
23namespace yaze {
24namespace zelda3 {
25struct GameData;
26} // namespace zelda3
27
28namespace editor {
29
34 public:
35 Tile16Editor(Rom* rom, gfx::Tilemap* tile16_blockset)
36 : session_(rom, tile16_blockset) {}
37
38 absl::Status Initialize(gfx::Bitmap& tile16_blockset_bmp,
39 gfx::Bitmap& current_gfx_bmp,
40 std::array<uint8_t, 0x200>& all_tiles_types);
41
42 absl::Status Update();
43 absl::Status UpdateAsPanel();
45 std::function<absl::Status(int, int)> callback) {
46 open_graphics_for_quadrant_ = std::move(callback);
47 }
48 void SetHoverDetailProvider(std::function<std::string(int)> provider) {
49 blockset_selector_.SetHoverDetailProvider(std::move(provider));
50 }
53 return absl::FailedPreconditionError("Graphics editor is unavailable");
54 }
57 }
58 // Main-menu items. The Overworld editor draws the edit actions in the main
59 // Edit menu and the view toggles and scratch slots in its own menu.
60 bool blockset_loaded() const { return session_.map_blockset_loaded(); }
61 void DrawEditMenuItems();
63 void DrawTile16Editor();
64 absl::Status UpdateBlockset();
65 void DrawScratchSpace();
66
67 absl::Status DrawToCurrentTile16(ImVec2 pos,
68 const gfx::Bitmap* source_tile = nullptr);
69 absl::Status HandleTile16CanvasClick(const ImVec2& tile_position,
70 bool left_click, bool right_click);
72 const ImVec2& display_position);
73
74 absl::Status UpdateTile16Edit();
75 absl::Status LoadTile8() { return session_.LoadTile8(); }
76 absl::Status SetCurrentTile(int id) { return session_.SetCurrentTile(id); }
77 void RequestTileSwitch(int target_tile_id) {
78 session_.RequestTileSwitch(target_tile_id);
79 }
80
81 absl::Status CopyTile16ToClipboard(int tile_id) {
82 return session_.CopyTile16ToClipboard(tile_id);
83 }
87 absl::Status SaveTile16ToScratchSpace(int slot) {
89 }
90 absl::Status LoadTile16FromScratchSpace(int slot) {
92 }
93 absl::Status ClearScratchSpace(int slot) {
94 return session_.ClearScratchSpace(slot);
95 }
96
97 absl::Status FlipTile16Horizontal() {
99 }
100 absl::Status FlipTile16Vertical() { return session_.FlipTile16Vertical(); }
101 absl::Status RotateTile16() { return session_.RotateTile16(); }
102 absl::Status FillTile16WithTile8(int tile8_id) {
103 return session_.FillTile16WithTile8(tile8_id);
104 }
105 absl::Status ClearTile16() { return session_.ClearTile16(); }
106
107 absl::Status CyclePalette(bool forward = true) {
108 return session_.CyclePalette(forward);
109 }
110 absl::Status ApplyPaletteToAll(uint8_t palette_id) {
111 return session_.ApplyPaletteToAll(palette_id);
112 }
113 absl::Status ApplyPaletteToQuadrant(int quadrant, uint8_t palette_id) {
114 return session_.ApplyPaletteToQuadrant(quadrant, palette_id);
115 }
116 absl::Status PreviewPaletteChange(uint8_t palette_id) {
117 return session_.PreviewPaletteChange(palette_id);
118 }
119
120 void BindDocument(std::vector<gfx::Tile16>* definitions, UndoManager* history,
121 std::function<void()> before_edit = {}) {
122 session_.BindDocument(definitions, history, std::move(before_edit));
123 }
124 absl::Status ReplaceCurrentTile(const gfx::Tile16& data,
125 uint64_t edit_group = 0) {
126 return session_.ReplaceCurrentTile(data, edit_group);
127 }
128 absl::Status Undo() { return session_.Undo(); }
129 absl::Status Redo() { return session_.Redo(); }
130 absl::StatusOr<std::unique_ptr<UndoAction>> PrepareDefinitionImport(
131 const std::vector<Tile16Commit>& definitions) {
132 return session_.PrepareDefinitionImport(definitions);
133 }
134
135 void EnableLivePreview(bool enable) { session_.EnableLivePreview(enable); }
136 absl::Status UpdateLivePreview() { return session_.UpdateLivePreview(); }
137
138 absl::Status ValidateTile16Data() { return session_.ValidateTile16Data(); }
139 bool IsTile16Valid(int tile_id) const {
140 return session_.IsTile16Valid(tile_id);
141 }
142
143 absl::Status SaveTile16ToROM() { return session_.SaveTile16ToROM(); }
144 absl::Status UpdateOverworldTilemap() {
146 }
147 absl::Status CommitChangesToBlockset() {
149 }
152 }
153 absl::Status DiscardChanges() { return session_.DiscardChanges(); }
154
157 bool is_tile_modified(int tile_id) const {
158 return session_.is_tile_modified(tile_id);
159 }
160 const gfx::Bitmap* GetPendingTileBitmap(int tile_id) const {
161 return session_.GetPendingTileBitmap(tile_id);
162 }
163
164 absl::Status CommitAllChanges() { return session_.CommitAllChanges(); }
168
169 absl::Status UpdateTile8Palette(int tile8_id) {
170 return session_.UpdateTile8Palette(tile8_id);
171 }
172 absl::Status RefreshAllPalettes() { return session_.RefreshAllPalettes(); }
173 void DrawPaletteSettings();
174
175 int GetActualPaletteSlot(int palette_button, int sheet_index) const {
176 return session_.GetActualPaletteSlot(palette_button, sheet_index);
177 }
178 int GetSheetIndexForTile8(int tile8_id) const {
179 return session_.GetSheetIndexForTile8(tile8_id);
180 }
185 const gfx::SnesPalette& source, int target_row) const {
186 return session_.CreateRemappedPaletteForViewing(source, target_row);
187 }
188 int GetEncodedPaletteRow(uint8_t pixel_value) const {
189 return session_.GetEncodedPaletteRow(pixel_value);
190 }
191
193 absl::Status RefreshTile16Blockset() {
195 }
202 absl::Status UpdateBlocksetBitmap() {
204 }
205 absl::Status PickTile8FromTile16(const ImVec2& position);
206
208
210 Rom* rom() const { return session_.rom(); }
215
216 void set_palette(const gfx::SnesPalette& palette) {
217 session_.set_palette(palette);
218 }
219
221 std::function<void(const std::vector<Tile16Commit>&)> callback) {
222 session_.set_on_document_changed(std::move(callback));
223 }
225 std::function<absl::Status(const std::vector<Tile16Commit>&)> callback) {
226 session_.set_on_changes_committed(std::move(callback));
227 }
228 void set_on_current_tile_changed(std::function<void(int)> callback) {
229 session_.set_on_current_tile_changed(std::move(callback));
230 }
231
232 int current_palette() const { return session_.current_palette(); }
233 // Updates display-only map collision labels; never changes the ROM/table.
234 void SetCollisionTypes(const std::array<uint8_t, 0x200>& types);
235 void ClearCollisionTypes();
236 void set_current_palette(int palette) {
238 }
242 int current_tile16() const { return session_.current_tile16(); }
246 int current_tile8() const { return session_.current_tile8(); }
247 int active_quadrant() const { return session_.active_quadrant(); }
248 void set_active_quadrant(int quadrant) {
250 }
253
255
256 absl::Status SaveLayoutToScratch(int slot) {
257 return session_.SaveLayoutToScratch(slot);
258 }
259 absl::Status LoadLayoutFromScratch(int slot);
260
261 private:
262 // Canvas uses ImVector<string> (byte copies); labels borrow this stable
263 // backing storage rather than temporary strings created during refresh.
264 std::array<std::string, 0x200> collision_label_storage_{};
267 absl::Status DrawTile16NavigationHeader(int total_tiles);
268 absl::Status DrawTile16EditorWorkbenchColumn(bool show_debug_info,
269 bool show_advanced_controls);
270
271 absl::Status DrawCompactActionStatusRow(bool* show_debug_info,
272 bool* show_advanced_controls);
273 absl::Status DrawBrushAndTilePaletteControls(bool show_debug_info);
274 absl::Status DrawTile8SourcePanel(float preferred_height = 0.0f);
275 absl::Status HandleTile8SourceSelection(bool right_clicked,
276 float display_scale);
277 absl::Status DrawPrimaryActionControls();
278
281
282 std::vector<int> selected_tiles_;
284 bool multi_select_mode_ = false;
285
288
295
296 gui::Canvas tile16_edit_canvas_{"Tile16EditCanvas", ImVec2(64, 64),
302
303 gui::Table tile_edit_table_{"##TileEditTable", 3, ImGuiTableFlags_Borders,
304 ImVec2(0, 0)};
305
307 absl::Status status_;
309 std::function<absl::Status(int, int)> open_graphics_for_quadrant_;
310 // One shared Undo step per open session of the manual properties dialog.
311 uint64_t manual_edit_group_ = 0;
312};
313
314} // namespace editor
315} // namespace yaze
316
317#endif // YAZE_APP_EDITOR_TILE16EDITOR_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:52
Allows the user to view and edit in game palettes.
Domain session for Tile16 editing (no ImGui).
int GetActualPaletteSlot(int palette_button, int sheet_index) const
gfx::SnesPalette CreateRemappedPaletteForViewing(const gfx::SnesPalette &source, int target_row) const
void set_on_current_tile_changed(std::function< void(int)> callback)
bool IsTile16Valid(int tile_id) const
zelda3::GameData * game_data() const
void set_palette(const gfx::SnesPalette &palette)
void set_on_document_changed(std::function< void(const std::vector< Tile16Commit > &)> callback)
absl::Status CyclePalette(bool forward=true)
absl::Status ApplyPaletteToAll(uint8_t palette_id)
void SetGameData(zelda3::GameData *game_data)
absl::Status CopyTile16ToClipboard(int tile_id)
absl::Status ReplaceCurrentTile(const gfx::Tile16 &data, uint64_t edit_group=0)
absl::Status PreviewPaletteChange(uint8_t palette_id)
absl::Status SaveLayoutToScratch(int slot)
absl::Status FillTile16WithTile8(int tile8_id)
absl::Status ApplyPaletteToQuadrant(int quadrant, uint8_t palette_id)
absl::Status LoadTile16FromScratchSpace(int slot)
void RequestTileSwitch(int target_tile_id)
absl::Status SaveTile16ToScratchSpace(int slot)
void set_on_changes_committed(std::function< absl::Status(const std::vector< Tile16Commit > &)> callback)
absl::Status UpdateTile8Palette(int tile8_id)
absl::StatusOr< std::unique_ptr< UndoAction > > PrepareDefinitionImport(const std::vector< Tile16Commit > &definitions, std::string description="Import Tile16 definitions")
int GetEncodedPaletteRow(uint8_t pixel_value) const
int GetSheetIndexForTile8(int tile8_id) const
const gfx::Bitmap & Tile8PreviewBitmap() const
bool is_tile_modified(int tile_id) const
const gfx::Bitmap * GetPendingTileBitmap(int tile_id) const
void BindDocument(std::vector< gfx::Tile16 > *definitions, UndoManager *history, std::function< void()> before_edit)
void set_edit_mode(Tile16EditMode mode)
absl::Status ClearScratchSpace(int slot)
ImGui façade for Tile16 editing; domain state lives in Tile16EditSession.
absl::Status SaveTile16ToScratchSpace(int slot)
Tile16Editor(Rom *rom, gfx::Tilemap *tile16_blockset)
absl::Status LoadLayoutFromScratch(int slot)
static ImVec2 Tile16PreviewDisplayPixelToTilePosition(const ImVec2 &display_position)
absl::Status DrawTile16EditorWorkbenchColumn(bool show_debug_info, bool show_advanced_controls)
zelda3::GameData * game_data() const
util::NotifyValue< uint32_t > notify_tile16
absl::Status CyclePalette(bool forward=true)
absl::Status HandleTile16CanvasClick(const ImVec2 &tile_position, bool left_click, bool right_click)
absl::Status FillTile16WithTile8(int tile8_id)
absl::Status CommitAllChanges()
int selected_tile16_for_testing() const
void AnalyzeTile8SourceData() const
absl::Status ApplyPaletteToAll(uint8_t palette_id)
std::function< absl::Status(int, int)> open_graphics_for_quadrant_
int GetActualPaletteSlotForCurrentTile16() const
void set_current_palette(int palette)
absl::Status RegenerateTile16BitmapFromROM()
void set_active_quadrant(int quadrant)
absl::Status HandleTile8SourceSelection(bool right_clicked, float display_scale)
absl::Status PasteTile16FromClipboard()
gui::TileSelectorWidget blockset_selector_
absl::Status SaveLayoutToScratch(int slot)
absl::Status LoadTile16FromScratchSpace(int slot)
gfx::SnesPalette CreateRemappedPaletteForViewing(const gfx::SnesPalette &source, int target_row) const
int GetActualPaletteSlot(int palette_button, int sheet_index) const
absl::Status FlipTile16Horizontal()
void SetGameData(zelda3::GameData *game_data)
void set_edit_mode(Tile16EditMode mode)
absl::Status OpenGraphicsForActiveQuadrant()
absl::Status DrawBrushAndTilePaletteControls(bool show_debug_info)
int GetEncodedPaletteRow(uint8_t pixel_value) const
std::array< std::string, 0x200 > collision_label_storage_
void EnableLivePreview(bool enable)
absl::Status DrawTile8SourcePanel(float preferred_height=0.0f)
Tile16EditMode edit_mode() const
void SetCollisionTypes(const std::array< uint8_t, 0x200 > &types)
absl::Status SetCurrentTile(int id)
absl::Status UpdateTile8Palette(int tile8_id)
absl::Status RefreshTile16Blockset()
void SetHoverDetailProvider(std::function< std::string(int)> provider)
absl::Status ValidateTile16Data()
void BindDocument(std::vector< gfx::Tile16 > *definitions, UndoManager *history, std::function< void()> before_edit={})
const gfx::Bitmap * GetPendingTileBitmap(int tile_id) const
absl::StatusOr< std::unique_ptr< UndoAction > > PrepareDefinitionImport(const std::vector< Tile16Commit > &definitions)
absl::Status RefreshAllPalettes()
void SetOpenGraphicsForQuadrant(std::function< absl::Status(int, int)> callback)
absl::Status ApplyPaletteToQuadrant(int quadrant, uint8_t palette_id)
void set_on_changes_committed(std::function< absl::Status(const std::vector< Tile16Commit > &)> callback)
absl::Status UpdateOverworldTilemap()
absl::Status DrawTile16NavigationHeader(int total_tiles)
absl::Status CommitChangesToBlockset()
absl::Status UpdateROMTile16Data()
void set_on_document_changed(std::function< void(const std::vector< Tile16Commit > &)> callback)
bool IsTile16Valid(int tile_id) const
gfx::Tile16 * GetCurrentTile16Data()
absl::Status DrawCompactActionStatusRow(bool *show_debug_info, bool *show_advanced_controls)
absl::Status CommitChangesToOverworld()
absl::Status UpdateBlocksetBitmap()
void RequestTileSwitch(int target_tile_id)
absl::Status DrawToCurrentTile16(ImVec2 pos, const gfx::Bitmap *source_tile=nullptr)
absl::Status UpdateLivePreview()
absl::Status Initialize(gfx::Bitmap &tile16_blockset_bmp, gfx::Bitmap &current_gfx_bmp, std::array< uint8_t, 0x200 > &all_tiles_types)
absl::Status ReplaceCurrentTile(const gfx::Tile16 &data, uint64_t edit_group=0)
absl::Status PreviewPaletteChange(uint8_t palette_id)
absl::Status CopyTile16ToClipboard(int tile_id)
const gfx::Bitmap & Tile8PreviewBitmapForTesting() const
absl::Status ClearScratchSpace(int slot)
bool is_tile_modified(int tile_id) const
int GetSheetIndexForTile8(int tile8_id) const
absl::Status FlipTile16Vertical()
Tile16EditSession session_
absl::Status PickTile8FromTile16(const ImVec2 &position)
std::vector< int > selected_tiles_
void set_palette(const gfx::SnesPalette &palette)
util::NotifyValue< uint8_t > notify_palette
void set_on_current_tile_changed(std::function< void(int)> callback)
Manages undo/redo stacks for a single editor.
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:70
Shared graphical context across editors.
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
Tile composition of four 8x8 tiles.
Definition snes_tile.h:142
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:64
Reusable tile selector built on top of Canvas.
void SetHoverDetailProvider(std::function< std::string(int)> provider)
Extra hover tooltip line for a tile (empty string adds nothing).
A class to manage a value that can be modified and notify when it changes.
Definition notify.h:13
constexpr int kTilesheetEditorHeight
constexpr int kTilesheetEditorWidth
constexpr int kTilesheetHeight
Definition snes_tile.h:17
constexpr int kTilesheetWidth
Definition snes_tile.h:16
Tilemap structure for SNES tile-based graphics management.
Definition tilemap.h:118