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 <chrono>
6#include <functional>
7#include <vector>
8
9#include "absl/status/status.h"
11#include "app/gfx/bitmap.h"
13#include "app/gfx/snes_tile.h"
14#include "app/gui/canvas.h"
15#include "app/gui/input.h"
16#include "util/log.h"
17#include "app/rom.h"
18#include "imgui/imgui.h"
19#include "util/notify.h"
20
21namespace yaze {
22namespace editor {
23
24// Constants for tile editing
25constexpr int kTile16Size = 16;
26constexpr int kTile8Size = 8;
27constexpr int kTilesheetEditorWidth = 0x100;
28constexpr int kTilesheetEditorHeight = 0x4000;
29constexpr int kTile16CanvasSize = 0x20;
30constexpr int kTile8CanvasHeight = 0x175;
31constexpr int kNumScratchSlots = 4;
32constexpr int kNumPalettes = 8;
33constexpr int kTile8PixelCount = 64;
34constexpr int kTile16PixelCount = 256;
35
40 public:
41 Tile16Editor(Rom* rom, gfx::Tilemap* tile16_blockset)
42 : rom_(rom), tile16_blockset_(tile16_blockset) {}
43 absl::Status Initialize(const gfx::Bitmap& tile16_blockset_bmp,
44 const gfx::Bitmap& current_gfx_bmp,
45 std::array<uint8_t, 0x200>& all_tiles_types);
46
47 absl::Status Update();
48
49 void DrawTile16Editor();
50 absl::Status UpdateBlockset();
51
52 // Scratch space for tile16 layouts
53 void DrawScratchSpace();
54 absl::Status SaveLayoutToScratch(int slot);
55 absl::Status LoadLayoutFromScratch(int slot);
56
57 absl::Status DrawToCurrentTile16(ImVec2 pos, const gfx::Bitmap* source_tile = nullptr);
58
59 absl::Status UpdateTile16Edit();
60
61 absl::Status LoadTile8();
62
63 absl::Status SetCurrentTile(int id);
64
65 // New methods for clipboard and scratch space
66 absl::Status CopyTile16ToClipboard(int tile_id);
67 absl::Status PasteTile16FromClipboard();
68 absl::Status SaveTile16ToScratchSpace(int slot);
69 absl::Status LoadTile16FromScratchSpace(int slot);
70 absl::Status ClearScratchSpace(int slot);
71
72 // Advanced editing features
73 absl::Status FlipTile16Horizontal();
74 absl::Status FlipTile16Vertical();
75 absl::Status RotateTile16();
76 absl::Status FillTile16WithTile8(int tile8_id);
77 absl::Status AutoTileTile16();
78 absl::Status ClearTile16();
79
80 // Palette management
81 absl::Status CyclePalette(bool forward = true);
82 absl::Status ApplyPaletteToAll(uint8_t palette_id);
83 absl::Status PreviewPaletteChange(uint8_t palette_id);
84
85 // Batch operations
86 absl::Status ApplyToSelection(const std::function<void(int)>& operation);
87 absl::Status BatchEdit(const std::vector<int>& tile_ids,
88 const std::function<void(int)>& operation);
89
90 // History and undo system
91 absl::Status Undo();
92 absl::Status Redo();
93 void SaveUndoState();
94
95 // Live preview system
96 void EnableLivePreview(bool enable) { live_preview_enabled_ = enable; }
97 absl::Status UpdateLivePreview();
98
99 // Validation and integrity checks
100 absl::Status ValidateTile16Data();
101 bool IsTile16Valid(int tile_id) const;
102
103 // Integration with overworld system
104 absl::Status SaveTile16ToROM();
105 absl::Status UpdateOverworldTilemap();
106 absl::Status CommitChangesToBlockset();
107 absl::Status CommitChangesToOverworld();
108 absl::Status DiscardChanges();
109
110 // Helper methods for palette management
111 absl::Status UpdateTile8Palette(int tile8_id);
112 absl::Status RefreshAllPalettes();
113 void DrawPaletteSettings();
114
115 // Get the appropriate palette slot for current graphics sheet
116 int GetPaletteSlotForSheet(int sheet_index) const;
117
118 // NEW: Core palette mapping methods for fixing color alignment
119 int GetActualPaletteSlot(int palette_button, int sheet_index) const;
120 int GetSheetIndexForTile8(int tile8_id) const;
122
123
124 // ROM data access and modification
125 absl::Status UpdateROMTile16Data();
126 absl::Status RefreshTile16Blockset();
128 absl::Status RegenerateTile16BitmapFromROM();
129 absl::Status UpdateBlocksetBitmap();
130 absl::Status PickTile8FromTile16(const ImVec2& position);
131
132 // Manual tile8 input controls
134
135 void set_rom(Rom* rom) { rom_ = rom; }
136 Rom* rom() const { return rom_; }
137
138 // Set the palette from overworld to ensure color consistency
139 void set_palette(const gfx::SnesPalette& palette) {
140 palette_ = palette;
141
142 // Store the complete 256-color overworld palette
143 if (palette.size() >= 256) {
144 overworld_palette_ = palette;
145 util::logf("Tile16 editor received complete overworld palette with %zu colors", palette.size());
146 } else {
147 util::logf("Warning: Received incomplete palette with %zu colors", palette.size());
148 overworld_palette_ = palette;
149 }
150
151 // CRITICAL FIX: Load tile8 graphics now that we have the proper palette
153 auto status = LoadTile8();
154 if (!status.ok()) {
155 util::logf("Failed to load tile8 graphics with new palette: %s", status.message().data());
156 } else {
157 util::logf("Successfully loaded tile8 graphics with complete overworld palette");
158 }
159 }
160
161 util::logf("Tile16 editor palette coordination complete");
162 }
163
164 // Callback for when changes are committed to notify parent editor
165 void set_on_changes_committed(std::function<absl::Status()> callback) {
166 on_changes_committed_ = callback;
167 }
168
169 private:
170 Rom* rom_ = nullptr;
172 bool x_flip = false;
173 bool y_flip = false;
174 bool priority_tile = false;
175
179 uint8_t current_palette_ = 0;
180
181 // Clipboard for Tile16 graphics
184
185 // Scratch space for Tile16 graphics (4 slots)
186 std::array<gfx::Bitmap, 4> scratch_space_;
187 std::array<bool, 4> scratch_space_used_ = {false, false, false, false};
188
189 // Layout scratch space for tile16 arrangements (4 slots of 8x8 grids)
191 std::array<std::array<int, 8>, 8> tile_layout; // 8x8 grid of tile16 IDs
192 bool in_use = false;
193 std::string name = "Empty";
194 };
195 std::array<LayoutScratch, 4> layout_scratch_;
196
197 // Undo/Redo system
205 std::vector<UndoState> undo_stack_;
206 std::vector<UndoState> redo_stack_;
207 static constexpr size_t kMaxUndoStates_ = 50;
208
209 // Live preview system
212 bool preview_dirty_ = false;
213
214 // Selection system
215 std::vector<int> selected_tiles_;
217 bool multi_select_mode_ = false;
218
219 // Advanced editing state
220 bool auto_tile_mode_ = false;
222 bool show_tile_info_ = true;
224
225 // Palette management settings
227 int current_palette_group_ = 0; // 0=overworld_main, 1=aux1, 2=aux2, etc.
228 uint8_t palette_normalization_mask_ = 0xFF; // Default 8-bit mask (preserve full palette index)
229 bool auto_normalize_pixels_ = false; // Disabled by default to preserve palette offsets
230
231 // Performance tracking
232 std::chrono::steady_clock::time_point last_edit_time_;
233 bool batch_mode_ = false;
234
237
238 std::array<uint8_t, 0x200> all_tiles_types_;
239
240 // Tile16 blockset for selecting the tile to edit
245
246 // Canvas for editing the selected tile - optimized for 2x2 grid of 8x8 tiles (16x16 total)
248 ImVec2(64, 64), // Fixed 64x64 display size (16x16 pixels at 4x scale)
249 gui::CanvasGridSize::k8x8, 8.0F}; // 8x8 grid with 4x scale for clarity
251
252 // Tile8 canvas to get the tile to drawing in the tile16_edit_canvas_
258
259 gui::Table tile_edit_table_{"##TileEditTable", 3, ImGuiTableFlags_Borders, ImVec2(0, 0)};
260
262 std::vector<gfx::Bitmap> current_gfx_individual_;
263
266 gfx::SnesPalette overworld_palette_; // Complete 256-color overworld palette
267
268 absl::Status status_;
269
270 // Callback to notify parent editor when changes are committed
271 std::function<absl::Status()> on_changes_committed_;
272
273 // Instance variable to store current tile16 data for proper persistence
275};
276
277} // namespace editor
278} // namespace yaze
279
280#endif // YAZE_APP_EDITOR_TILE16EDITOR_H
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:71
Allows the user to view and edit in game palettes.
Popup window to edit Tile16 data.
absl::Status SaveTile16ToScratchSpace(int slot)
Tile16Editor(Rom *rom, gfx::Tilemap *tile16_blockset)
absl::Status LoadLayoutFromScratch(int slot)
std::chrono::steady_clock::time_point last_edit_time_
util::NotifyValue< uint32_t > notify_tile16
absl::Status CyclePalette(bool forward=true)
absl::Status BatchEdit(const std::vector< int > &tile_ids, const std::function< void(int)> &operation)
absl::Status FillTile16WithTile8(int tile8_id)
gfx::Tilemap * tile16_blockset_
absl::Status ApplyPaletteToAll(uint8_t palette_id)
int GetActualPaletteSlotForCurrentTile16() const
absl::Status AutoTileTile16()
std::array< uint8_t, 0x200 > all_tiles_types_
absl::Status RegenerateTile16BitmapFromROM()
absl::Status PasteTile16FromClipboard()
absl::Status SaveLayoutToScratch(int slot)
absl::Status LoadTile16FromScratchSpace(int slot)
int GetPaletteSlotForSheet(int sheet_index) const
int GetActualPaletteSlot(int palette_button, int sheet_index) const
std::vector< UndoState > undo_stack_
absl::Status FlipTile16Horizontal()
gfx::SnesPalette overworld_palette_
absl::Status Initialize(const gfx::Bitmap &tile16_blockset_bmp, const gfx::Bitmap &current_gfx_bmp, std::array< uint8_t, 0x200 > &all_tiles_types)
void EnableLivePreview(bool enable)
absl::Status SetCurrentTile(int id)
absl::Status UpdateTile8Palette(int tile8_id)
absl::Status RefreshTile16Blockset()
std::array< gfx::Bitmap, 4 > scratch_space_
std::vector< UndoState > redo_stack_
absl::Status UpdateOverworldTilemap()
absl::Status CommitChangesToBlockset()
std::array< LayoutScratch, 4 > layout_scratch_
absl::Status UpdateROMTile16Data()
bool IsTile16Valid(int tile_id) const
gfx::Tile16 * GetCurrentTile16Data()
absl::Status ApplyToSelection(const std::function< void(int)> &operation)
std::vector< gfx::Bitmap > current_gfx_individual_
absl::Status CommitChangesToOverworld()
absl::Status UpdateBlocksetBitmap()
absl::Status DrawToCurrentTile16(ImVec2 pos, const gfx::Bitmap *source_tile=nullptr)
absl::Status UpdateLivePreview()
absl::Status PreviewPaletteChange(uint8_t palette_id)
absl::Status CopyTile16ToClipboard(int tile_id)
absl::Status ClearScratchSpace(int slot)
std::function< absl::Status()> on_changes_committed_
static constexpr size_t kMaxUndoStates_
int GetSheetIndexForTile8(int tile8_id) const
std::array< bool, 4 > scratch_space_used_
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_changes_committed(std::function< absl::Status()> callback)
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:66
bool is_active() const
Definition bitmap.h:264
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:137
Modern, robust canvas for drawing and manipulating graphics.
Definition canvas.h:54
A class to manage a value that can be modified and notify when it changes.
Definition notify.h:13
constexpr int kTile16PixelCount
constexpr int kTile8PixelCount
constexpr int kTile16CanvasSize
constexpr int kTile8Size
constexpr int kTilesheetEditorHeight
constexpr int kTile16Size
constexpr int kNumScratchSlots
constexpr int kTile8CanvasHeight
constexpr int kNumPalettes
constexpr int kTilesheetEditorWidth
constexpr int kTilesheetHeight
Definition snes_tile.h:17
constexpr int kTilesheetWidth
Definition snes_tile.h:16
void logf(const absl::FormatSpec< Args... > &format, Args &&... args)
Definition log.h:116
Main namespace for the application.
std::array< std::array< int, 8 >, 8 > tile_layout
Tilemap structure for SNES tile-based graphics management.
Definition tilemap.h:109