yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
graphics_editor.cc
Go to the documentation of this file.
1// Related header
2#include "graphics_editor.h"
3
4// C++ standard library headers
5#include <filesystem>
6
7// Third-party library headers
8#include "absl/status/status.h"
9#include "absl/status/statusor.h"
10#include "absl/strings/str_cat.h"
11#include "imgui/imgui.h"
12#include "imgui/misc/cpp/imgui_stdlib.h"
13
14// Project headers
17#include "app/gfx/core/bitmap.h"
25#include "app/gui/core/color.h"
26#include "app/gui/core/icons.h"
27#include "app/gui/core/input.h"
28#include "app/gui/core/style.h"
32#include "app/platform/window.h"
33#include "rom/rom.h"
34#include "rom/snes.h"
35#include "util/file_util.h"
36#include "util/log.h"
37
38namespace yaze {
39namespace editor {
40
42using ImGui::Button;
43using ImGui::InputInt;
44using ImGui::InputText;
45using ImGui::SameLine;
46
49 return;
50 auto* panel_manager = dependencies_.panel_manager;
51
52 // Initialize panel components
53 sheet_browser_panel_ = std::make_unique<SheetBrowserPanel>(&state_);
54 pixel_editor_panel_ = std::make_unique<PixelEditorPanel>(&state_, rom_);
55 palette_controls_panel_ = std::make_unique<PaletteControlsPanel>(&state_, rom_);
56 link_sprite_panel_ = std::make_unique<LinkSpritePanel>(&state_, rom_);
57 polyhedral_panel_ = std::make_unique<PolyhedralEditorPanel>(rom_);
58 gfx_group_panel_ = std::make_unique<GfxGroupEditor>();
59 gfx_group_panel_->SetRom(rom_);
60 gfx_group_panel_->SetGameData(game_data_);
61 paletteset_panel_ = std::make_unique<PalettesetEditorPanel>();
62 paletteset_panel_->SetRom(rom_);
63 paletteset_panel_->SetGameData(game_data_);
64
65 sheet_browser_panel_->Initialize();
66 pixel_editor_panel_->Initialize();
67 palette_controls_panel_->Initialize();
68 link_sprite_panel_->Initialize();
69
70 // Register panels using EditorPanel system with callbacks
71 panel_manager->RegisterEditorPanel(
72 std::make_unique<GraphicsSheetBrowserPanel>([this]() {
74 status_ = sheet_browser_panel_->Update();
75 }
76 }));
77
78 panel_manager->RegisterEditorPanel(
79 std::make_unique<GraphicsPixelEditorPanel>([this]() {
81 status_ = pixel_editor_panel_->Update();
82 }
83 }));
84
85 panel_manager->RegisterEditorPanel(
86 std::make_unique<GraphicsPaletteControlsPanel>([this]() {
89 }
90 }));
91
92 panel_manager->RegisterEditorPanel(
93 std::make_unique<GraphicsLinkSpritePanel>([this]() {
95 status_ = link_sprite_panel_->Update();
96 }
97 }));
98
99 panel_manager->RegisterEditorPanel(
100 std::make_unique<GraphicsPolyhedralPanel>([this]() {
101 if (polyhedral_panel_) {
102 status_ = polyhedral_panel_->Update();
103 }
104 }));
105
106 panel_manager->RegisterEditorPanel(
107 std::make_unique<GraphicsGfxGroupPanel>([this]() {
108 if (gfx_group_panel_) {
109 status_ = gfx_group_panel_->Update();
110 }
111 }));
112
113 // Paletteset editor panel (separated from GfxGroupEditor for better UX)
114 panel_manager->RegisterEditorPanel(
115 std::make_unique<GraphicsPalettesetPanel>([this]() {
116 if (paletteset_panel_) {
117 status_ = paletteset_panel_->Update();
118 }
119 }));
120
121 // Prototype viewer for Super Donkey and dev format imports
122 panel_manager->RegisterEditorPanel(
123 std::make_unique<GraphicsPrototypeViewerPanel>([this]() {
125 }));
126}
127
128absl::Status GraphicsEditor::Load() {
129 gfx::ScopedTimer timer("GraphicsEditor::Load");
130
131 // Initialize all graphics sheets with appropriate palettes from ROM
132 // This ensures textures are created for editing
133 if (rom()->is_loaded()) {
134 auto& sheets = gfx::Arena::Get().gfx_sheets();
135
136 // Apply default palettes to all sheets based on common SNES ROM structure
137 // Sheets 0-112: Use overworld/dungeon palettes
138 // Sheets 113-127: Use sprite palettes
139 // Sheets 128-222: Use auxiliary/menu palettes
140
141 LOG_INFO("GraphicsEditor", "Initializing textures for %d graphics sheets",
143
144 int sheets_queued = 0;
145 for (int i = 0; i < zelda3::kNumGfxSheets; i++) {
146 if (!sheets[i].is_active() || !sheets[i].surface()) {
147 continue; // Skip inactive or surface-less sheets
148 }
149
150 // Palettes are now applied during ROM loading in LoadAllGraphicsData()
151 // Just queue texture creation for sheets that don't have textures yet
152 if (!sheets[i].texture()) {
153 // Fix: Ensure default palettes are applied if missing
154 // This handles the case where sheets are loaded but have no palette assigned
155 if (sheets[i].palette().empty()) {
156 // Default palette assignment logic
157 if (i <= 112) {
158 // Overworld/Dungeon sheets - use Dungeon Main palette (Group 0, Index 0)
159 if (game_data() && game_data()->palette_groups.dungeon_main.size() > 0) {
160 sheets[i].SetPaletteWithTransparent(
161 game_data()->palette_groups.dungeon_main.palette(0), 0);
162 }
163 } else if (i >= 113 && i <= 127) {
164 // Sprite sheets - use Sprites Aux1 palette (Group 4, Index 0)
165 if (game_data() && game_data()->palette_groups.sprites_aux1.size() > 0) {
166 sheets[i].SetPaletteWithTransparent(
167 game_data()->palette_groups.sprites_aux1.palette(0), 0);
168 }
169 } else {
170 // Menu/Aux sheets - use HUD palette if available, or fallback
171 if (game_data() && game_data()->palette_groups.hud.size() > 0) {
172 sheets[i].SetPaletteWithTransparent(
173 game_data()->palette_groups.hud.palette(0), 0);
174 }
175 }
176 }
177
180 sheets_queued++;
181 }
182 }
183
184 LOG_INFO("GraphicsEditor", "Queued texture creation for %d graphics sheets",
185 sheets_queued);
186 }
187
188 if (polyhedral_panel_) {
189 polyhedral_panel_->SetRom(rom_);
191 }
192
193 return absl::OkStatus();
194}
195
196absl::Status GraphicsEditor::Save() {
197 if (!rom_ || !rom_->is_loaded()) {
198 return absl::FailedPreconditionError("ROM not loaded");
199 }
200
201 // Only save sheets that have been modified
202 if (!state_.HasUnsavedChanges()) {
203 LOG_INFO("GraphicsEditor", "No modified sheets to save");
204 return absl::OkStatus();
205 }
206
207 LOG_INFO("GraphicsEditor", "Saving %zu modified graphics sheets",
208 state_.modified_sheets.size());
209
210 auto& sheets = gfx::Arena::Get().gfx_sheets();
211
212 for (uint16_t sheet_id : state_.modified_sheets) {
213 if (sheet_id >= zelda3::kNumGfxSheets) continue;
214
215 auto& sheet = sheets[sheet_id];
216 if (!sheet.is_active()) continue;
217
218 // Determine BPP and compression based on sheet range
219 int bpp = 3; // Default 3BPP
220 bool compressed = true;
221
222 // Sheets 113-114, 218+ are 2BPP
223 if (sheet_id == 113 || sheet_id == 114 || sheet_id >= 218) {
224 bpp = 2;
225 }
226
227 // Sheets 115-126 are uncompressed
228 if (sheet_id >= 115 && sheet_id <= 126) {
229 compressed = false;
230 }
231
232 // Convert 8BPP bitmap data to SNES indexed format
233 auto indexed_data = gfx::Bpp8SnesToIndexed(sheet.vector(), bpp);
234
235 std::vector<uint8_t> final_data;
236 if (compressed) {
237 // Compress using Hyrule Magic LC-LZ2
238 int compressed_size = 0;
239 auto compressed_data = gfx::HyruleMagicCompress(
240 indexed_data.data(), static_cast<int>(indexed_data.size()),
241 &compressed_size, 1);
242 final_data.assign(compressed_data.begin(),
243 compressed_data.begin() + compressed_size);
244 } else {
245 final_data = std::move(indexed_data);
246 }
247
248 // Calculate ROM offset for this sheet
249 // Get version constants from game_data
250 auto version_constants = zelda3::kVersionConstantsMap.at(game_data()->version);
251 uint32_t offset = zelda3::GetGraphicsAddress(
252 rom_->data(), static_cast<uint8_t>(sheet_id),
253 version_constants.kOverworldGfxPtr1,
254 version_constants.kOverworldGfxPtr2,
255 version_constants.kOverworldGfxPtr3, rom_->size());
256
257 // Write data to ROM buffer
258 for (size_t i = 0; i < final_data.size(); i++) {
259 rom_->WriteByte(offset + i, final_data[i]);
260 }
261
262 LOG_INFO("GraphicsEditor", "Saved sheet %02X (%zu bytes, %s) at offset %06X",
263 sheet_id, final_data.size(), compressed ? "compressed" : "raw",
264 offset);
265 }
266
267 // Clear modified tracking after successful save
269
270 return absl::OkStatus();
271}
272
274 // Panels are now drawn via PanelManager::DrawAllVisiblePanels()
275 // This Update() only handles editor-level state and keyboard shortcuts
276
277 // Handle editor-level keyboard shortcuts
279
281 return absl::OkStatus();
282}
283
285 // Skip if ImGui wants keyboard input
286 if (ImGui::GetIO().WantTextInput) {
287 return;
288 }
289
290 // Tool shortcuts (only when graphics editor is active)
291 if (ImGui::IsKeyPressed(ImGuiKey_V, false)) {
293 }
294 if (ImGui::IsKeyPressed(ImGuiKey_B, false)) {
296 }
297 if (ImGui::IsKeyPressed(ImGuiKey_E, false)) {
299 }
300 if (ImGui::IsKeyPressed(ImGuiKey_G, false) && !ImGui::GetIO().KeyCtrl) {
302 }
303 if (ImGui::IsKeyPressed(ImGuiKey_I, false)) {
305 }
306 if (ImGui::IsKeyPressed(ImGuiKey_L, false) && !ImGui::GetIO().KeyCtrl) {
308 }
309 if (ImGui::IsKeyPressed(ImGuiKey_R, false) && !ImGui::GetIO().KeyCtrl) {
311 }
312
313 // Zoom shortcuts
314 if (ImGui::IsKeyPressed(ImGuiKey_Equal, false) ||
315 ImGui::IsKeyPressed(ImGuiKey_KeypadAdd, false)) {
316 state_.ZoomIn();
317 }
318 if (ImGui::IsKeyPressed(ImGuiKey_Minus, false) ||
319 ImGui::IsKeyPressed(ImGuiKey_KeypadSubtract, false)) {
320 state_.ZoomOut();
321 }
322
323 // Grid toggle (Ctrl+G)
324 if (ImGui::GetIO().KeyCtrl && ImGui::IsKeyPressed(ImGuiKey_G, false)) {
326 }
327
328 // Sheet navigation
329 if (ImGui::IsKeyPressed(ImGuiKey_PageDown, false)) {
330 NextSheet();
331 }
332 if (ImGui::IsKeyPressed(ImGuiKey_PageUp, false)) {
333 PrevSheet();
334 }
335}
336
339 ImGui::Begin("Memory Editor", &open_memory_editor_);
341 ImGui::End();
342 }
343
344 constexpr ImGuiTableFlags kGfxEditFlags = ImGuiTableFlags_Reorderable |
345 ImGuiTableFlags_Resizable |
346 ImGuiTableFlags_SizingStretchSame;
347
348 BEGIN_TABLE("#gfxEditTable", 4, kGfxEditFlags)
349 SETUP_COLUMN("File Import (BIN, CGX, ROM)")
350 SETUP_COLUMN("Palette (COL)")
351 ImGui::TableSetupColumn("Tilemaps and Objects (SCR, PNL, OBJ)",
352 ImGuiTableColumnFlags_WidthFixed);
353 SETUP_COLUMN("Graphics Preview")
355 NEXT_COLUMN() {
360 }
361
362 NEXT_COLUMN() {
364 }
365
368 scr_loaded_, false, 0);
370
372 if (super_donkey_) {
373 // Super Donkey prototype graphics
374 for (size_t i = 0; i < num_sheets_to_load_ && i < gfx_sheets_.size(); i++) {
375 if (gfx_sheets_[i].is_active() && gfx_sheets_[i].texture()) {
376 ImGui::Image((ImTextureID)(intptr_t)gfx_sheets_[i].texture(),
377 ImVec2(128, 32));
378 if ((i + 1) % 4 != 0) {
379 ImGui::SameLine();
380 }
381 }
382 }
383 } else if (cgx_loaded_ && col_file_) {
384 // Load the CGX graphics
386 cgx_loaded_, true, 5);
387 } else {
388 // Load the BIN/Clipboard Graphics
390 gfx_loaded_, true, 2);
391 }
392 END_TABLE()
393}
394
395// =============================================================================
396// Prototype Viewer Import Methods
397// =============================================================================
398
400 gui::TextWithSeparators("Cgx Import");
401 InputInt("BPP", &current_bpp_);
402
403 InputText("##CGXFile", &cgx_file_name_);
404 SameLine();
405
406 if (ImGui::Button("Open CGX")) {
408 cgx_file_name_ = filename;
409 cgx_file_path_ = std::filesystem::absolute(filename).string();
410 is_open_ = true;
411 cgx_loaded_ = true;
412 }
413
414 if (ImGui::Button("Copy CGX Path")) {
415 ImGui::SetClipboardText(cgx_file_path_.c_str());
416 }
417
418 if (ImGui::Button("Load CGX Data")) {
421
422 cgx_bitmap_.Create(0x80, 0x200, 8, decoded_cgx_);
423 if (col_file_) {
427 }
428 }
429
430 return absl::OkStatus();
431}
432
434 InputText("##ScrFile", &scr_file_name_);
435
436 if (ImGui::Button("Open SCR")) {
438 scr_file_name_ = filename;
439 scr_file_path_ = std::filesystem::absolute(filename).string();
440 is_open_ = true;
441 scr_loaded_ = true;
442 }
443
444 InputInt("SCR Mod", &scr_mod_value_);
445
446 if (ImGui::Button("Load Scr Data")) {
448
449 decoded_scr_data_.resize(0x100 * 0x100);
452
453 scr_bitmap_.Create(0x100, 0x100, 8, decoded_scr_data_);
454 if (scr_loaded_) {
458 }
459 }
460
461 return absl::OkStatus();
462}
463
465 gui::TextWithSeparators("COL Import");
466 InputText("##ColFile", &col_file_name_);
467 SameLine();
468
469 if (ImGui::Button("Open COL")) {
471 col_file_name_ = filename;
472 col_file_path_ = std::filesystem::absolute(filename).string();
474 auto col_data_ = gfx::GetColFileData(temp_rom_.mutable_data());
475 if (col_file_palette_group_.size() != 0) {
477 }
478 auto col_file_palette_group_status =
480 if (col_file_palette_group_status.ok()) {
481 col_file_palette_group_ = col_file_palette_group_status.value();
482 }
484
485 // gigaleak dev format based code
487 col_file_ = true;
488 is_open_ = true;
489 }
490 HOVER_HINT(".COL, .BAK");
491
492 if (ImGui::Button("Copy Col Path")) {
493 ImGui::SetClipboardText(col_file_path_.c_str());
494 }
495
496 if (rom()->is_loaded()) {
497 gui::TextWithSeparators("ROM Palette");
498 gui::InputHex("Palette Index", &current_palette_index_);
499 ImGui::Combo("Palette", &current_palette_, kPaletteGroupAddressesKeys,
500 IM_ARRAYSIZE(kPaletteGroupAddressesKeys));
501 }
502
503 if (col_file_palette_.size() != 0) {
506 }
507
508 return absl::OkStatus();
509}
510
512 gui::TextWithSeparators("OBJ Import");
513
514 InputText("##ObjFile", &obj_file_path_);
515 SameLine();
516
517 if (ImGui::Button("Open OBJ")) {
519 obj_file_path_ = std::filesystem::absolute(filename).string();
521 is_open_ = true;
522 obj_loaded_ = true;
523 }
524 HOVER_HINT(".OBJ, .BAK");
525
526 return absl::OkStatus();
527}
528
530 gui::TextWithSeparators("Tilemap Import");
531
532 InputText("##TMapFile", &tilemap_file_path_);
533 SameLine();
534
535 if (ImGui::Button("Open Tilemap")) {
537 tilemap_file_path_ = std::filesystem::absolute(filename).string();
540
541 // Extract the high and low bytes from the file.
542 auto decomp_sheet = gfx::lc_lz2::DecompressV2(tilemap_rom_.data(), 0, 0x800,
545 tilemap_loaded_ = true;
546 is_open_ = true;
547 }
548 HOVER_HINT(".DAT, .BIN, .HEX");
549
550 return absl::OkStatus();
551}
552
554 gui::TextWithSeparators("BIN Import");
555
556 InputText("##ROMFile", &file_path_);
557 SameLine();
558
559 if (ImGui::Button("Open BIN")) {
561 file_path_ = filename;
563 is_open_ = true;
564 }
565 HOVER_HINT(".BIN, .HEX");
566
567 if (Button("Copy File Path")) {
568 ImGui::SetClipboardText(file_path_.c_str());
569 }
570
571 gui::InputHex("BIN Offset", &current_offset_);
572 gui::InputHex("BIN Size", &bin_size_);
573
574 if (Button("Decompress BIN")) {
575 if (file_path_.empty()) {
576 return absl::InvalidArgumentError(
577 "Please select a file before decompressing.");
578 }
580 }
581
582 return absl::OkStatus();
583}
584
586 gui::TextWithSeparators("Clipboard Import");
587 if (Button("Paste From Clipboard")) {
588 const char* text = ImGui::GetClipboardText();
589 if (text) {
590 const auto clipboard_data =
591 std::vector<uint8_t>(text, text + strlen(text));
592 ImGui::MemFree((void*)text);
593 status_ = temp_rom_.LoadFromData(clipboard_data);
594 is_open_ = true;
595 open_memory_editor_ = true;
596 }
597 }
600 gui::InputHex("Num Sheets", &num_sheets_to_load_);
601
602 if (Button("Decompress Clipboard Data")) {
603 if (temp_rom_.is_loaded()) {
604 status_ = DecompressImportData(0x40000);
605 } else {
606 status_ = absl::InvalidArgumentError(
607 "Please paste data into the clipboard before "
608 "decompressing.");
609 }
610 }
611
612 return absl::OkStatus();
613}
614
616 gui::TextWithSeparators("Experimental");
617 if (Button("Decompress Super Donkey Full")) {
618 if (file_path_.empty()) {
619 return absl::InvalidArgumentError(
620 "Please select `super_donkey_1.bin` before "
621 "importing.");
622 }
624 }
625 ImGui::SetItemTooltip(
626 "Requires `super_donkey_1.bin` to be imported under the "
627 "BIN import section.");
628 return absl::OkStatus();
629}
630
632 std::string title = "Memory Editor";
633 if (is_open_) {
634 static yaze::gui::MemoryEditorWidget mem_edit;
635 mem_edit.DrawWindow(title.c_str(), temp_rom_.mutable_data(),
636 temp_rom_.size());
637 }
638 return absl::OkStatus();
639}
640
643 temp_rom_.data(), current_offset_, size, 1,
644 temp_rom_.size()));
645
646 auto converted_sheet = gfx::SnesTo8bppSheet(import_data_, 3);
648 converted_sheet);
649
650 if (rom()->is_loaded() && game_data()) {
651 auto palette_group = game_data()->palette_groups.overworld_animated;
652 z3_rom_palette_ = palette_group[current_palette_];
653 if (col_file_) {
655 } else {
657 }
658 }
659
661 &bin_bitmap_);
662 gfx_loaded_ = true;
663
664 return absl::OkStatus();
665}
666
668 int i = 0;
669 for (const auto& offset : kSuperDonkeyTiles) {
670 int offset_value =
671 std::stoi(offset, nullptr, 16); // convert hex string to int
673 auto decompressed_data,
674 gfx::lc_lz2::DecompressV2(temp_rom_.data(), offset_value, 0x1000, 1,
675 temp_rom_.size()));
676 auto converted_sheet = gfx::SnesTo8bppSheet(decompressed_data, 3);
678 gfx::kTilesheetDepth, converted_sheet);
679 if (col_file_) {
680 gfx_sheets_[i].SetPalette(
682 } else {
683 // ROM palette
684 if (!game_data()) {
685 return absl::FailedPreconditionError("GameData not available");
686 }
687 auto palette_group = game_data()->palette_groups.get_group(
688 kPaletteGroupAddressesKeys[current_palette_]);
689 z3_rom_palette_ = palette_group->palette(current_palette_index_);
690 gfx_sheets_[i].SetPalette(z3_rom_palette_);
691 }
692
695 i++;
696 }
697
698 for (const auto& offset : kSuperDonkeySprites) {
699 int offset_value =
700 std::stoi(offset, nullptr, 16); // convert hex string to int
702 auto decompressed_data,
703 gfx::lc_lz2::DecompressV2(temp_rom_.data(), offset_value, 0x1000, 1,
704 temp_rom_.size()));
705 auto converted_sheet = gfx::SnesTo8bppSheet(decompressed_data, 3);
707 gfx::kTilesheetDepth, converted_sheet);
708 if (col_file_) {
709 gfx_sheets_[i].SetPalette(
711 } else {
712 // ROM palette
713 if (game_data()) {
714 auto palette_group = game_data()->palette_groups.get_group(
715 kPaletteGroupAddressesKeys[current_palette_]);
716 z3_rom_palette_ = palette_group->palette(current_palette_index_);
717 gfx_sheets_[i].SetPalette(z3_rom_palette_);
718 }
719 }
720
723 i++;
724 }
725 super_donkey_ = true;
727
728 return absl::OkStatus();
729}
730
736
742
743} // namespace editor
744} // namespace yaze
absl::Status LoadFromFile(const std::string &filename, const LoadOptions &options=LoadOptions::Defaults())
Definition rom.cc:74
absl::Status WriteByte(int addr, uint8_t value)
Definition rom.cc:286
auto mutable_data()
Definition rom.h:136
auto data() const
Definition rom.h:135
auto size() const
Definition rom.h:134
absl::Status LoadFromData(const std::vector< uint8_t > &data, const LoadOptions &options=LoadOptions::Defaults())
Definition rom.cc:147
bool is_loaded() const
Definition rom.h:128
zelda3::GameData * game_data() const
Definition editor.h:228
EditorDependencies dependencies_
Definition editor.h:237
bool HasUnsavedChanges() const
Check if any sheets have unsaved changes.
void SetTool(PixelTool tool)
Set the current editing tool.
void ClearModifiedSheets()
Clear modification tracking (after save)
std::vector< uint8_t > scr_data_
absl::Status Save() override
gfx::PaletteGroup col_file_palette_group_
absl::Status Load() override
std::unique_ptr< GfxGroupEditor > gfx_group_panel_
std::unique_ptr< PaletteControlsPanel > palette_controls_panel_
std::vector< uint8_t > decoded_cgx_
std::vector< uint8_t > cgx_data_
std::unique_ptr< PixelEditorPanel > pixel_editor_panel_
std::unique_ptr< PolyhedralEditorPanel > polyhedral_panel_
std::unique_ptr< PalettesetEditorPanel > paletteset_panel_
std::vector< uint8_t > import_data_
std::vector< SDL_Color > decoded_col_
absl::Status Update() override
std::vector< uint8_t > extra_cgx_data_
std::array< gfx::Bitmap, zelda3::kNumGfxSheets > gfx_sheets_
std::vector< uint8_t > decoded_scr_data_
std::unique_ptr< LinkSpritePanel > link_sprite_panel_
absl::Status DecompressImportData(int size)
std::unique_ptr< SheetBrowserPanel > sheet_browser_panel_
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
Definition arena.cc:34
std::array< gfx::Bitmap, 223 > & gfx_sheets()
Get reference to all graphics sheets.
Definition arena.h:101
static Arena & Get()
Definition arena.cc:19
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
void Create(int width, int height, int depth, std::span< uint8_t > data)
Create a bitmap with the given dimensions and data.
Definition bitmap.cc:199
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap using SNES palette format.
Definition bitmap.cc:382
RAII timer for automatic timing management.
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
#define LOG_INFO(category, format,...)
Definition log.h:105
#define SETUP_COLUMN(l)
Definition macro.h:12
#define END_TABLE()
Definition macro.h:20
#define TABLE_HEADERS()
Definition macro.h:14
#define BEGIN_TABLE(l, n, f)
Definition macro.h:11
#define NEXT_COLUMN()
Definition macro.h:18
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Definition macro.h:62
#define CLEAR_AND_RETURN_STATUS(status)
Definition macro.h:97
#define HOVER_HINT(string)
Definition macro.h:24
const std::string kSuperDonkeySprites[]
const std::string kSuperDonkeyTiles[]
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
Definition compression.h:54
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
Definition snes_tile.h:17
constexpr int kTilesheetWidth
Definition snes_tile.h:16
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
Definition snes_tile.h:18
std::vector< uint8_t > Bpp8SnesToIndexed(std::vector< uint8_t > data, uint64_t bpp)
Definition snes_tile.cc:202
std::vector< uint8_t > SnesTo8bppSheet(std::span< uint8_t > sheet, int bpp, int num_sheets)
Definition snes_tile.cc:131
std::vector< uint8_t > HyruleMagicCompress(uint8_t const *const src, int const oldsize, int *const size, int const flag)
absl::StatusOr< PaletteGroup > CreatePaletteGroupFromColFile(std::vector< SnesColor > &palette_rows)
std::vector< SnesColor > GetColFileData(uint8_t *data)
Definition snes_color.cc:91
void BitmapCanvasPipeline(gui::Canvas &canvas, gfx::Bitmap &bitmap, int width, int height, int tile_size, bool is_loaded, bool scrollbar, int canvas_id)
Definition canvas.cc:1669
bool InputHex(const char *label, uint64_t *data)
Definition input.cc:325
void SelectablePalettePipeline(uint64_t &palette_id, bool &refresh_graphics, gfx::SnesPalette &palette)
Definition color.cc:309
void TextWithSeparators(const absl::string_view &text)
Definition style.cc:1317
constexpr uint32_t kNumGfxSheets
Definition game_data.h:25
uint32_t GetGraphicsAddress(const uint8_t *data, uint8_t addr, uint32_t ptr1, uint32_t ptr2, uint32_t ptr3, size_t rom_size)
Gets the graphics address for a sheet index.
Definition game_data.cc:69
#define RETURN_IF_ERROR(expr)
Definition snes.cc:22
PaletteGroup * get_group(const std::string &group_name)
void DrawWindow(const char *title, void *mem_data, size_t mem_size, size_t base_display_addr=0x0000)
gfx::PaletteGroupMap palette_groups
Definition game_data.h:89