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 <algorithm>
5#include <array>
6#include <chrono>
7#include <functional>
8#include <map>
9#include <optional>
10#include <string>
11#include <utility>
12#include <vector>
13
14#include "absl/status/status.h"
18#include "app/gfx/core/bitmap.h"
22#include "app/gui/core/input.h"
24#include "imgui/imgui.h"
25#include "rom/rom.h"
26#include "util/log.h"
27#include "util/notify.h"
30
31namespace yaze {
32namespace zelda3 {
33struct GameData;
34} // namespace zelda3
35
36namespace editor {
37
38// ============================================================================
39// Tile16 Editor Constants
40// ============================================================================
41
42constexpr int kTile16Size = 16; // 16x16 pixel tile
43constexpr int kTile8Size = 8; // 8x8 pixel sub-tile
44constexpr int kTilesheetEditorWidth = 0x100; // 256 pixels wide
45constexpr int kTilesheetEditorHeight = 0x4000; // 16384 pixels tall
46constexpr int kTile16CanvasSize = 0x20; // 32 pixels
47constexpr int kTile8CanvasHeight = 0x175; // 373 pixels
48constexpr int kNumScratchSlots = 4; // 4 scratch space slots
49constexpr int kNumPalettes = 8; // 8 palette buttons (0-7)
50constexpr int kTile8PixelCount = 64; // 8x8 = 64 pixels
51constexpr int kTile16PixelCount = 256; // 16x16 = 256 pixels
52
53enum class Tile16EditMode {
54 kPaint = 0,
55 kPick = 1,
56 kUsageProbe = 2,
57};
58
64
70
75
76// ============================================================================
77// Tile16 Editor
78// ============================================================================
79//
80// ARCHITECTURE OVERVIEW:
81// ----------------------
82// The Tile16Editor provides a popup window for editing individual 16x16 tiles
83// used in the overworld tileset. Each Tile16 is composed of four 8x8 sub-tiles
84// (Tile8) arranged in a 2x2 grid.
85//
86// EDITING WORKFLOW:
87// -----------------
88// 1. Select a Tile16 from the blockset canvas (left panel)
89// 2. Edit by clicking on the tile8 source canvas to select sub-tiles
90// 3. Place selected tile8s into the four quadrants of the Tile16
91// 4. Changes are held as "pending" until explicitly committed or discarded
92// 5. Commit saves to ROM; Discard reverts to original
93//
94// PENDING CHANGES SYSTEM:
95// -----------------------
96// To prevent accidental ROM modifications, all edits are staged:
97// - pending_tile16_changes_: Maps tile ID -> modified Tile16 data
98// - pending_tile16_bitmaps_: Maps tile ID -> preview bitmap
99// - has_pending_changes(): Returns true if any tiles are modified
100// - CommitAllChanges(): Writes all pending changes to ROM
101// - DiscardAllChanges(): Reverts all pending changes
102//
103// PALETTE COORDINATION:
104// ---------------------
105// The overworld uses a 256-color palette organized as 16 rows of 16 colors.
106// Tile16 metadata stores a 3-bit palette row (0-7), matching ZScream and the
107// SNES tilemap word. Graphics sheet pixels contribute the low nibble, including
108// whether the source uses the left or right half of the selected row.
109//
110// Key palette methods:
111// - GetActualPaletteSlot(): Convert palette button 0-7 to row * 16
112// - GetActualPaletteSlotForCurrentTile16(): Get current brush row slot
113// - ApplyPaletteToCurrentTile16Bitmap(): Apply correct colors to preview
114//
115// INTEGRATION WITH OVERWORLD:
116// ---------------------------
117// The Tile16Editor communicates with OverworldEditor via:
118// - set_palette(): Called when overworld area changes (updates colors)
119// - on_changes_committed_: Callback invoked after CommitAllChanges()
120// - The callback triggers RefreshTile16Blockset() and RefreshOverworldMap()
121//
122// See README.md in this directory for complete documentation.
123// ============================================================================
124
134 public:
135 Tile16Editor(Rom* rom, gfx::Tilemap* tile16_blockset)
136 : rom_(rom), tile16_blockset_(tile16_blockset) {}
137 absl::Status Initialize(gfx::Bitmap& tile16_blockset_bmp,
138 gfx::Bitmap& current_gfx_bmp,
139 std::array<uint8_t, 0x200>& all_tiles_types);
140
141 absl::Status Update();
142
149 absl::Status UpdateAsPanel();
150
157 void DrawContextMenu();
158
159 void DrawTile16Editor();
160 absl::Status UpdateBlockset();
161
162 // Scratch space for tile16 layouts
163 void DrawScratchSpace();
164 absl::Status SaveLayoutToScratch(int slot);
165 absl::Status LoadLayoutFromScratch(int slot);
166
167 absl::Status DrawToCurrentTile16(ImVec2 pos,
168 const gfx::Bitmap* source_tile = nullptr);
169 absl::Status HandleTile16CanvasClick(const ImVec2& tile_position,
170 bool left_click, bool right_click);
172 const ImVec2& display_position);
173
174 absl::Status UpdateTile16Edit();
175
176 absl::Status LoadTile8();
177
178 absl::Status SetCurrentTile(int id);
179
180 // Request a tile switch - shows confirmation dialog if current tile has pending changes
181 void RequestTileSwitch(int target_tile_id);
182
183 // New methods for clipboard and scratch space
184 absl::Status CopyTile16ToClipboard(int tile_id);
185 absl::Status PasteTile16FromClipboard();
186 absl::Status SaveTile16ToScratchSpace(int slot);
187 absl::Status LoadTile16FromScratchSpace(int slot);
188 absl::Status ClearScratchSpace(int slot);
189
190 // Advanced editing features
191 absl::Status FlipTile16Horizontal();
192 absl::Status FlipTile16Vertical();
193 absl::Status RotateTile16();
194 absl::Status FillTile16WithTile8(int tile8_id);
195 absl::Status ClearTile16();
196
197 // Palette management
198 absl::Status CyclePalette(bool forward = true);
199 absl::Status ApplyPaletteToAll(uint8_t palette_id);
200 absl::Status ApplyPaletteToQuadrant(int quadrant, uint8_t palette_id);
201 absl::Status PreviewPaletteChange(uint8_t palette_id);
202
203 // History and undo system
204 absl::Status Undo();
205 absl::Status Redo();
206 void SaveUndoState();
207
208 // Live preview system
209 void EnableLivePreview(bool enable) { live_preview_enabled_ = enable; }
210 absl::Status UpdateLivePreview();
211
212 // Validation and integrity checks
213 absl::Status ValidateTile16Data();
214 bool IsTile16Valid(int tile_id) const;
215
216 // ===========================================================================
217 // Integration with Overworld System
218 // ===========================================================================
219 // These methods handle the connection between tile editing and ROM data.
220 // The workflow is: Edit -> Pending -> Commit -> ROM
221
223 absl::Status SaveTile16ToROM();
224
226 absl::Status UpdateOverworldTilemap();
227
229 absl::Status CommitChangesToBlockset();
230
233 absl::Status CommitChangesToOverworld();
234
236 absl::Status DiscardChanges();
237
238 // ===========================================================================
239 // Pending Changes System
240 // ===========================================================================
241 // All tile edits are staged in memory before being written to ROM.
242 // This prevents accidental modifications and allows preview before commit.
243 //
244 // Usage:
245 // 1. Edit tiles normally (changes go to pending_tile16_changes_)
246 // 2. Check has_pending_changes() to show save/discard UI
247 // 3. User clicks Save -> CommitAllChanges()
248 // 4. User clicks Discard -> DiscardAllChanges()
249 //
250 // The on_changes_committed_ callback notifies OverworldEditor to refresh.
251
253 bool has_pending_changes() const { return !pending_tile16_changes_.empty(); }
254
257 return static_cast<int>(pending_tile16_changes_.size());
258 }
259
261 bool is_tile_modified(int tile_id) const {
262 return pending_tile16_changes_.find(tile_id) !=
264 }
265
267 const gfx::Bitmap* GetPendingTileBitmap(int tile_id) const {
268 auto it = pending_tile16_bitmaps_.find(tile_id);
269 return it != pending_tile16_bitmaps_.end() ? &it->second : nullptr;
270 }
271
273 absl::Status CommitAllChanges();
274
276 void DiscardAllChanges();
277
280
283
284 // ===========================================================================
285 // Palette Coordination System
286 // ===========================================================================
287 // The overworld uses a 256-color palette organized as 16 rows of 16 colors.
288 // Tile16 palette buttons map directly to CGRAM rows 0-7. Source graphics
289 // keep their low nibble, so pixels from either half of a row still render
290 // against the same palette row the Tile16 metadata will save.
291 //
292 // Palette Structure (256 colors = 16 rows × 16 colors):
293 // Row 0: Transparent/system colors
294 // Row 1: HUD colors (0x10-0x1F)
295 // Rows 2-6: MAIN/BG palettes
296 // Row 7: ANIMATED palette
297 // Rows 8-15: Sprite/auxiliary palette halves
298 //
299 // The palette button (0-7) selects the saved Tile16 palette row directly.
300
302 absl::Status UpdateTile8Palette(int tile8_id);
303
305 absl::Status RefreshAllPalettes();
306
308 void DrawPaletteSettings();
309
317 int GetActualPaletteSlot(int palette_button, int sheet_index) const;
318
322 int GetSheetIndexForTile8(int tile8_id) const;
323
327
333 const gfx::SnesPalette& source, int target_row) const;
334
338 int GetEncodedPaletteRow(uint8_t pixel_value) const;
339
340 // ROM data access and modification
341 absl::Status UpdateROMTile16Data();
342 absl::Status RefreshTile16Blockset();
344 absl::Status RegenerateTile16BitmapFromROM();
345 absl::Status UpdateBlocksetBitmap();
346 absl::Status PickTile8FromTile16(const ImVec2& position);
347
348 // Manual tile8 input controls
350
351 void SetRom(Rom* rom) { rom_ = rom; }
352 Rom* rom() const { return rom_; }
355
356 // Set the palette from overworld to ensure color consistency
357 void set_palette(const gfx::SnesPalette& palette) {
358 palette_ = palette;
359
360 // Store the complete 256-color overworld palette
361 if (palette.size() >= 256) {
362 overworld_palette_ = palette;
364 "Tile16 editor received complete overworld palette with %zu colors",
365 palette.size());
366 } else {
367 util::logf("Warning: Received incomplete palette with %zu colors",
368 palette.size());
369 overworld_palette_ = palette;
370 }
371
372 // CRITICAL FIX: Load tile8 graphics now that we have the proper palette
374 auto status = LoadTile8();
375 if (!status.ok()) {
376 util::logf("Failed to load tile8 graphics with new palette: %s",
377 status.message().data());
378 } else {
380 "Successfully loaded tile8 graphics with complete overworld "
381 "palette");
382 }
383 }
384
385 util::logf("Tile16 editor palette coordination complete");
386 }
387
388 // Callback for when changes are committed to notify parent editor
390 std::function<absl::Status(const std::vector<Tile16Commit>&)> callback) {
391 on_changes_committed_ = callback;
392 }
393
396 void set_on_current_tile_changed(std::function<void(int)> callback) {
397 on_current_tile_changed_ = std::move(callback);
398 }
399
400 // Accessors for testing and external use
401 int current_palette() const { return current_palette_; }
402 void set_current_palette(int palette) {
403 current_palette_ = static_cast<uint8_t>(std::clamp(palette, 0, 7));
404 }
408 int current_tile16() const { return current_tile16_; }
412 int current_tile8() const { return current_tile8_; }
413 int active_quadrant() const { return active_quadrant_; }
414 void set_active_quadrant(int quadrant) {
415 active_quadrant_ = std::clamp(quadrant, 0, 3);
416 }
419
420 // Diagnostic function to analyze tile8 source data format
421 void AnalyzeTile8SourceData() const;
422
423 private:
424 Rom* rom_ = nullptr;
427 bool x_flip = false;
428 bool y_flip = false;
429 bool priority_tile = false;
430
432 int target_row,
433 int tile8_id) const;
434
438 uint8_t current_palette_ = 0;
441
442 // Clipboard for Tile16 graphics and metadata
444
445 // Scratch space for Tile16 graphics and metadata (4 slots)
446 std::array<Tile16ScratchData, 4> scratch_space_;
447
448 // Layout scratch space for tile16 arrangements (4 slots of 8x8 grids)
450 std::array<std::array<int, 8>, 8> tile_layout; // 8x8 grid of tile16 IDs
451 bool in_use = false;
452 std::string name = "Empty";
453 };
454 std::array<LayoutScratch, 4> layout_scratch_;
455
456 // Undo/Redo system (unified UndoManager framework)
458 std::optional<Tile16Snapshot> pending_undo_before_;
459
462 void FinalizePendingUndo();
463
465 void RestoreFromSnapshot(const Tile16Snapshot& snapshot);
466
467 // Live preview system
470 bool preview_dirty_ = false;
472 tile8_preview_bmp_; // Persistent preview to keep arena commands valid
473
474 // Selection system
475 std::vector<int> selected_tiles_;
477 bool multi_select_mode_ = false;
478
479 // Advanced editing state
480 bool auto_tile_mode_ = false;
482 bool show_tile_info_ = true;
484 bool show_tile_grid_ = true;
486 int tile8_stamp_size_ = 1; // ZScream parity: 1x, 2x, 4x tile8 stamping.
489
492
493 // Palette management settings
495 int current_palette_group_ = 0; // 0=overworld_main, 1=aux1, 2=aux2, etc.
497 0xFF; // Default 8-bit mask (preserve full palette index)
499 false; // Disabled by default to preserve palette offsets
500
501 // Performance tracking
502 std::chrono::steady_clock::time_point last_edit_time_;
503 bool batch_mode_ = false;
504
505 // Pending changes system for batch preview/commit workflow
506 std::map<int, gfx::Tile16> pending_tile16_changes_;
507 std::map<int, gfx::Bitmap> pending_tile16_bitmaps_;
509 int pending_tile_switch_target_ = -1; // Target tile for pending switch
512 std::chrono::steady_clock::time_point last_rom_write_time_{};
513
514 // Navigation controls for expanded tile support
515 int jump_to_tile_id_ = 0; // Input field for jump to tile ID
516 bool scroll_to_current_ = false; // Flag to scroll to current tile
517 int current_page_ = 0; // Current page (64 tiles per page)
518 static constexpr int kTilesPerPage = 64; // 8x8 tiles per page
519 static constexpr int kTilesPerRow = 8; // Tiles per row in grid
520
523
524 std::array<uint8_t, 0x200> all_tiles_types_;
525
526 // Tile16 blockset for selecting the tile to edit
534
535 // Canvas for editing the selected tile - optimized for 2x2 grid of 8x8 tiles
536 // (16x16 total)
538 "Tile16EditCanvas",
539 ImVec2(64, 64), // Fixed 64x64 display size (16x16 pixels at 4x scale)
540 gui::CanvasGridSize::k8x8, 8.0F}; // 8x8 grid with 4x scale for clarity
542
543 // Tile8 canvas to get the tile to drawing in the tile16_edit_canvas_
549
550 gui::Table tile_edit_table_{"##TileEditTable", 3, ImGuiTableFlags_Borders,
551 ImVec2(0, 0)};
552
554 std::vector<zelda3::Tile8PixelData> current_gfx_individual_;
555
558 gfx::SnesPalette overworld_palette_; // Complete 256-color overworld palette
559
560 absl::Status status_;
561
562 // Callback to notify parent editor when changes are committed
563 std::function<absl::Status(const std::vector<Tile16Commit>&)>
565 std::function<void(int)> on_current_tile_changed_;
566
567 // Instance variable to store current tile16 data for proper persistence
569
570 // Apply the active palette (overworld area if available) to the current
571 // tile16 bitmap using sheet-aware offsets.
573
574 // Resolve the best available 256-color palette source for tile previews.
576
577 // Detect whether bitmap pixels already encode non-zero palette rows.
578 bool BitmapHasEncodedPaletteRows(const gfx::Bitmap& bitmap) const;
579
580 // Build a 16x16 bitmap for a tile from TileInfo metadata using the shared
581 // palette/index transform path.
582 absl::Status BuildTile16BitmapFromData(const gfx::Tile16& tile_data,
583 gfx::Bitmap* output_bitmap) const;
584
585 // Copy a 16x16 tile bitmap into the blockset preview and atlas at tile_id.
586 void CopyTileBitmapToBlockset(int tile_id, const gfx::Bitmap& tile_bitmap);
587
588 // Rebuild and render reverse-usage highlight overlays (ZScream parity).
589 absl::Status RebuildTile8UsageCache();
591
592 // Handle keyboard shortcuts (shared between Update and UpdateAsPanel)
594
595 bool HasCurrentGfxBitmap() const {
596 return current_gfx_bmp_ != nullptr && current_gfx_bmp_->is_active();
597 }
598
601 }
602
603 // Copy current tile16 bitmap pixels into the blockset atlas at the given
604 // tile position. Consolidates the repeated 16x16 copy loops.
605 void CopyTile16ToAtlas(int tile_id);
606
607 // Draw the compact action/status row for staged Tile16 edits.
608 absl::Status DrawCompactActionStatusRow(bool has_pending,
609 bool current_tile_pending,
610 int pending_count,
611 bool* show_debug_info,
612 bool* show_advanced_controls);
613
614 // Draw brush palette controls and tile palette metadata controls.
615 absl::Status DrawBrushAndTilePaletteControls(bool show_debug_info);
616
617 // Draw the Tile8 source column and handle source selection interaction.
618 absl::Status DrawTile8SourcePanel(float preferred_height = 0.0f);
619 absl::Status HandleTile8SourceSelection(bool right_clicked,
620 float display_scale);
621
622 // Draw primary local edit controls in the right action column.
623 absl::Status DrawPrimaryActionControls();
624};
625
626} // namespace editor
627} // namespace yaze
628
629#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:28
Allows the user to view and edit in game palettes.
Popup window to edit Tile16 data.
absl::Status SaveTile16ToScratchSpace(int slot)
const gfx::SnesPalette * ResolveDisplayPalette() const
Tile16Editor(Rom *rom, gfx::Tilemap *tile16_blockset)
std::function< absl::Status(const std::vector< Tile16Commit > &) on_changes_committed_)
std::map< int, gfx::Tile16 > pending_tile16_changes_
absl::Status LoadLayoutFromScratch(int slot)
static ImVec2 Tile16PreviewDisplayPixelToTilePosition(const ImVec2 &display_position)
zelda3::GameData * game_data() const
void FinalizePendingUndo()
Finalize any pending undo snapshot by capturing current state as "after" and pushing a Tile16EditActi...
std::chrono::steady_clock::time_point last_edit_time_
util::NotifyValue< uint32_t > notify_tile16
void DrawContextMenu()
Draw context menu with editor actions.
absl::Status CyclePalette(bool forward=true)
absl::Status HandleTile16CanvasClick(const ImVec2 &tile_position, bool left_click, bool right_click)
std::chrono::steady_clock::time_point last_rom_write_time_
absl::Status FillTile16WithTile8(int tile8_id)
gfx::Tilemap * tile16_blockset_
bool BitmapHasEncodedPaletteRows(const gfx::Bitmap &bitmap) const
absl::Status CommitAllChanges()
Write all pending changes to ROM and notify parent.
std::map< int, gfx::Bitmap > pending_tile16_bitmaps_
int selected_tile16_for_testing() const
std::array< Tile16ScratchData, 4 > scratch_space_
absl::Status SaveTile16ToROM()
Write current tile16 data directly to ROM (bypasses pending system)
void RestoreFromSnapshot(const Tile16Snapshot &snapshot)
Restore editor state from a Tile16Snapshot (used by undo actions).
absl::Status ApplyPaletteToAll(uint8_t palette_id)
void DiscardAllChanges()
Discard all pending changes (revert to ROM state)
int GetActualPaletteSlotForCurrentTile16() const
Get the palette slot for the current tile being edited.
void set_current_palette(int palette)
std::array< uint8_t, 0x200 > all_tiles_types_
absl::Status RegenerateTile16BitmapFromROM()
std::function< void(int)> on_current_tile_changed_
void set_active_quadrant(int quadrant)
absl::Status DiscardChanges()
Discard current tile's changes (single tile)
absl::Status HandleTile8SourceSelection(bool right_clicked, float display_scale)
absl::Status PasteTile16FromClipboard()
gui::TileSelectorWidget blockset_selector_
int pending_changes_count() const
Get count of tiles with pending changes.
absl::Status SaveLayoutToScratch(int slot)
absl::Status LoadTile16FromScratchSpace(int slot)
gfx::SnesPalette CreateRemappedPaletteForViewing(const gfx::SnesPalette &source, int target_row) const
Create a remapped palette for viewing with user-selected palette.
int GetActualPaletteSlot(int palette_button, int sheet_index) const
Calculate actual palette slot from button.
absl::Status FlipTile16Horizontal()
gfx::Bitmap * tile16_blockset_bmp_
void SetGameData(zelda3::GameData *game_data)
std::vector< zelda3::Tile8PixelData > current_gfx_individual_
void set_edit_mode(Tile16EditMode mode)
gfx::SnesPalette overworld_palette_
static constexpr int kTilesPerPage
absl::Status DrawBrushAndTilePaletteControls(bool show_debug_info)
int GetEncodedPaletteRow(uint8_t pixel_value) const
Get the encoded palette row for a pixel value.
static constexpr int kTilesPerRow
void EnableLivePreview(bool enable)
absl::Status DrawTile8SourcePanel(float preferred_height=0.0f)
Tile16EditMode edit_mode() const
absl::Status SetCurrentTile(int id)
absl::Status UpdateTile8Palette(int tile8_id)
Update palette for a specific tile8.
zelda3::Tile8UsageIndex tile8_usage_cache_
absl::Status UpdateAsPanel()
Update the editor content without MenuBar (for WindowContent usage)
absl::Status RefreshTile16Blockset()
Tile16ClipboardData clipboard_tile16_
const gfx::Bitmap * GetPendingTileBitmap(int tile_id) const
Get preview bitmap for a pending tile (nullptr if not modified)
zelda3::GameData * game_data_
absl::Status RefreshAllPalettes()
Refresh all tile8 palettes after a palette change.
bool HasTile16BlocksetBitmap() const
void DrawPaletteSettings()
Draw palette settings UI.
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()
Update the overworld tilemap to reflect tile changes.
absl::Status CommitChangesToBlockset()
Commit pending changes to the blockset atlas.
std::array< LayoutScratch, 4 > layout_scratch_
absl::Status UpdateROMTile16Data()
gfx::SnesPalette CreateRemappedPaletteForTile8(const gfx::SnesPalette &source, int target_row, int tile8_id) const
std::optional< Tile16Snapshot > pending_undo_before_
bool IsTile16Valid(int tile_id) const
gfx::Tile16 * GetCurrentTile16Data()
void MarkCurrentTileModified()
Mark the current tile as having pending changes.
absl::Status RebuildTile8UsageCache()
bool has_pending_changes() const
Check if any tiles have uncommitted changes.
absl::Status CommitChangesToOverworld()
Single-tile commit: ROM + blockset + parent refresh callback. Prefer CommitAllChanges() from the main...
absl::Status UpdateBlocksetBitmap()
void DiscardCurrentTileChanges()
Discard only the current tile's pending changes.
void RequestTileSwitch(int target_tile_id)
absl::Status DrawToCurrentTile16(ImVec2 pos, const gfx::Bitmap *source_tile=nullptr)
absl::Status Initialize(gfx::Bitmap &tile16_blockset_bmp, gfx::Bitmap &current_gfx_bmp, std::array< uint8_t, 0x200 > &all_tiles_types)
absl::Status DrawCompactActionStatusRow(bool has_pending, bool current_tile_pending, int pending_count, bool *show_debug_info, bool *show_advanced_controls)
void CopyTileBitmapToBlockset(int tile_id, const gfx::Bitmap &tile_bitmap)
absl::Status PreviewPaletteChange(uint8_t palette_id)
absl::Status CopyTile16ToClipboard(int tile_id)
absl::Status DrawPrimaryActionControls()
const gfx::Bitmap & Tile8PreviewBitmapForTesting() const
absl::Status ClearScratchSpace(int slot)
bool is_tile_modified(int tile_id) const
Check if a specific tile has pending changes.
absl::Status BuildTile16BitmapFromData(const gfx::Tile16 &tile_data, gfx::Bitmap *output_bitmap) const
int GetSheetIndexForTile8(int tile8_id) const
Determine which graphics sheet contains a tile8.
absl::Status PickTile8FromTile16(const ImVec2 &position)
std::vector< int > selected_tiles_
void CopyTile16ToAtlas(int tile_id)
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:67
bool is_active() const
Definition bitmap.h:405
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.
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:115
std::array< std::vector< Tile8UsageHit >, kMaxTile8UsageId > Tile8UsageIndex
std::array< std::array< int, 8 >, 8 > tile_layout
Snapshot of a Tile16's editable state for undo/redo.
Tilemap structure for SNES tile-based graphics management.
Definition tilemap.h:118