yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
graphics_editor.cc
Go to the documentation of this file.
1#include "graphics_editor.h"
2
3#include <filesystem>
4
5#include "absl/status/status.h"
6#include "absl/status/statusor.h"
10#include "app/gfx/bitmap.h"
11#include "app/gfx/compression.h"
12#include "app/gfx/scad_format.h"
14#include "app/gfx/snes_tile.h"
15#include "app/gui/canvas.h"
16#include "app/gui/color.h"
17#include "app/gui/icons.h"
18#include "app/gui/input.h"
20#include "app/gui/style.h"
21#include "app/rom.h"
22#include "imgui/imgui.h"
23#include "imgui/misc/cpp/imgui_stdlib.h"
24#include "imgui_memory_editor.h"
25
26namespace yaze {
27namespace editor {
28
29using core::Renderer;
30
32using ImGui::Button;
33using ImGui::InputInt;
34using ImGui::InputText;
35using ImGui::SameLine;
36using ImGui::TableNextColumn;
37
38constexpr ImGuiTableFlags kGfxEditTableFlags =
39 ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable |
40 ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable |
41 ImGuiTableFlags_SizingFixedFit;
42
43absl::Status GraphicsEditor::Update() {
44 if (ImGui::BeginTabBar("##TabBar")) {
46 TAB_ITEM("Sheet Browser")
47 if (asset_browser_.Initialized == false) {
48 asset_browser_.Initialize(GraphicsSheetManager::GetInstance().gfx_sheets());
49 }
54 ImGui::EndTabBar();
55 }
57 return absl::OkStatus();
58}
59
61 if (ImGui::BeginTabItem("Sheet Editor")) {
62 if (ImGui::BeginTable("##GfxEditTable", 3, kGfxEditTableFlags,
63 ImVec2(0, 0))) {
64 for (const auto& name :
65 {"Tilesheets", "Current Graphics", "Palette Controls"})
66 ImGui::TableSetupColumn(name);
67
68 ImGui::TableHeadersRow();
69
72
74 if (rom()->is_loaded()) {
77 }
78
80 if (rom()->is_loaded()) {
82 }
83 }
84 ImGui::EndTable();
85
86 ImGui::EndTabItem();
87 }
88 return absl::OkStatus();
89}
90
92 if (ImGui::BeginTable("##GfxEditToolset", 9, ImGuiTableFlags_SizingFixedFit,
93 ImVec2(0, 0))) {
94 for (const auto& name :
95 {"Select", "Pencil", "Fill", "Copy Sheet", "Paste Sheet", "Zoom Out",
96 "Zoom In", "Current Color", "Tile Size"})
97 ImGui::TableSetupColumn(name);
98
99 TableNextColumn();
100 if (Button(ICON_MD_SELECT_ALL)) {
102 }
103
104 TableNextColumn();
105 if (Button(ICON_MD_DRAW)) {
107 }
108 HOVER_HINT("Draw with current color");
109
110 TableNextColumn();
111 if (Button(ICON_MD_FORMAT_COLOR_FILL)) {
113 }
114 HOVER_HINT("Fill with current color");
115
116 TableNextColumn();
117 if (Button(ICON_MD_CONTENT_COPY)) {
118 std::vector<uint8_t> png_data =
121 }
122 HOVER_HINT("Copy to Clipboard");
123
124 TableNextColumn();
125 if (Button(ICON_MD_CONTENT_PASTE)) {
126 std::vector<uint8_t> png_data;
127 int width, height;
128 core::GetImageFromClipboard(png_data, width, height);
129 if (png_data.size() > 0) {
131 ->at(current_sheet_)
132 .Create(width, height, 8, png_data);
134 &GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(current_sheet_));
135 }
136 }
137 HOVER_HINT("Paste from Clipboard");
138
139 TableNextColumn();
140 if (Button(ICON_MD_ZOOM_OUT)) {
141 if (current_scale_ >= 0.0f) {
142 current_scale_ -= 1.0f;
143 }
144 }
145
146 TableNextColumn();
147 if (Button(ICON_MD_ZOOM_IN)) {
148 if (current_scale_ <= 16.0f) {
149 current_scale_ += 1.0f;
150 }
151 }
152
153 TableNextColumn();
155 auto palette = bitmap.palette();
156 for (int i = 0; i < palette.size(); i++) {
157 ImGui::SameLine();
158 auto color =
159 ImVec4(palette[i].rgb().x / 255.0f, palette[i].rgb().y / 255.0f,
160 palette[i].rgb().z / 255.0f, 255.0f);
161 if (ImGui::ColorButton(absl::StrFormat("Palette Color %d", i).c_str(),
162 color)) {
163 current_color_ = color;
164 }
165 }
166
167 TableNextColumn();
168 gui::InputHexByte("Tile Size", &tile_size_);
169
170 ImGui::EndTable();
171 }
172}
173
175 ImGui::BeginChild(
176 "##GfxEditChild", ImVec2(0, 0), true,
177 ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysVerticalScrollbar);
178 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
179 // TODO: Update the interaction for multi select on sheets
180 static ImGuiSelectionBasicStorage selection;
181 ImGuiMultiSelectFlags flags =
182 ImGuiMultiSelectFlags_ClearOnEscape | ImGuiMultiSelectFlags_BoxSelect1d;
183 ImGuiMultiSelectIO* ms_io =
184 ImGui::BeginMultiSelect(flags, selection.Size, kNumGfxSheets);
185 selection.ApplyRequests(ms_io);
186 ImGuiListClipper clipper;
187 clipper.Begin(kNumGfxSheets);
188 if (ms_io->RangeSrcItem != -1)
189 clipper.IncludeItemByIndex(
190 (int)ms_io->RangeSrcItem); // Ensure RangeSrc item is not clipped.
191
192 int key = 0;
193 for (auto& value : GraphicsSheetManager::GetInstance().gfx_sheets()) {
194 ImGui::BeginChild(absl::StrFormat("##GfxSheet%02X", key).c_str(),
195 ImVec2(0x100 + 1, 0x40 + 1), true,
196 ImGuiWindowFlags_NoDecoration);
197 ImGui::PopStyleVar();
198
199 graphics_bin_canvas_.DrawBackground(ImVec2(0x100 + 1, 0x40 + 1));
200 graphics_bin_canvas_.DrawContextMenu();
201 if (value.is_active()) {
202 auto texture = value.texture();
203 graphics_bin_canvas_.draw_list()->AddImage(
204 (ImTextureID)(intptr_t)texture,
205 ImVec2(graphics_bin_canvas_.zero_point().x + 2,
206 graphics_bin_canvas_.zero_point().y + 2),
207 ImVec2(graphics_bin_canvas_.zero_point().x +
208 value.width() * sheet_scale_,
209 graphics_bin_canvas_.zero_point().y +
210 value.height() * sheet_scale_));
211
212 if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
213 current_sheet_ = key;
214 open_sheets_.insert(key);
215 }
216
217 // Add a slightly transparent rectangle behind the text
218 ImVec2 text_pos(graphics_bin_canvas_.zero_point().x + 2,
219 graphics_bin_canvas_.zero_point().y + 2);
220 ImVec2 text_size =
221 ImGui::CalcTextSize(absl::StrFormat("%02X", key).c_str());
222 ImVec2 rent_min(text_pos.x, text_pos.y);
223 ImVec2 rent_max(text_pos.x + text_size.x, text_pos.y + text_size.y);
224
225 graphics_bin_canvas_.draw_list()->AddRectFilled(rent_min, rent_max,
226 IM_COL32(0, 125, 0, 128));
227
228 graphics_bin_canvas_.draw_list()->AddText(
229 text_pos, IM_COL32(125, 255, 125, 255),
230 absl::StrFormat("%02X", key).c_str());
231
232 key++;
233 }
234 graphics_bin_canvas_.DrawGrid(16.0f);
235 graphics_bin_canvas_.DrawOverlay();
236
237 ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
238 ImGui::EndChild();
239 }
240 ImGui::PopStyleVar();
241 ms_io = ImGui::EndMultiSelect();
242 selection.ApplyRequests(ms_io);
243 ImGui::EndChild();
244 return absl::OkStatus();
245}
246
248 static int next_tab_id = 0;
249 constexpr ImGuiTabBarFlags kGfxEditTabBarFlags =
250 ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable |
251 ImGuiTabBarFlags_FittingPolicyResizeDown |
252 ImGuiTabBarFlags_TabListPopupButton;
253
254 if (ImGui::BeginTabBar("##GfxEditTabBar", kGfxEditTabBarFlags)) {
255 if (ImGui::TabItemButton(ICON_MD_ADD, ImGuiTabItemFlags_Trailing |
256 ImGuiTabItemFlags_NoTooltip)) {
257 open_sheets_.insert(next_tab_id++);
258 }
259
260 for (auto& sheet_id : open_sheets_) {
261 bool open = true;
262 if (ImGui::BeginTabItem(absl::StrFormat("%d", sheet_id).c_str(), &open,
263 ImGuiTabItemFlags_None)) {
264 current_sheet_ = sheet_id;
265 if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) {
266 release_queue_.push(sheet_id);
267 }
268 if (ImGui::IsItemHovered()) {
269 if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
270 release_queue_.push(sheet_id);
271 child_window_sheets_.insert(sheet_id);
272 }
273 }
274
275 const auto child_id =
276 absl::StrFormat("##GfxEditPaletteChildWindow%d", sheet_id);
277 ImGui::BeginChild(child_id.c_str(), ImVec2(0, 0), true,
278 ImGuiWindowFlags_NoDecoration |
279 ImGuiWindowFlags_AlwaysVerticalScrollbar |
280 ImGuiWindowFlags_AlwaysHorizontalScrollbar);
281
282 gfx::Bitmap& current_bitmap = GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(sheet_id);
283
284 auto draw_tile_event = [&]() {
285 current_sheet_canvas_.DrawTileOnBitmap(tile_size_, &current_bitmap,
287 Renderer::GetInstance().UpdateBitmap(&current_bitmap);
288 };
289
290 current_sheet_canvas_.UpdateColorPainter(
291 GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(sheet_id), current_color_,
292 draw_tile_event, tile_size_, current_scale_);
293
294 ImGui::EndChild();
295 ImGui::EndTabItem();
296 }
297
298 if (!open) release_queue_.push(sheet_id);
299 }
300
301 ImGui::EndTabBar();
302 }
303
304 // Release any tabs that were closed
305 while (!release_queue_.empty()) {
306 auto sheet_id = release_queue_.top();
307 open_sheets_.erase(sheet_id);
308 release_queue_.pop();
309 }
310
311 // Draw any child windows that were created
312 if (!child_window_sheets_.empty()) {
313 int id_to_release = -1;
314 for (const auto& id : child_window_sheets_) {
315 bool active = true;
316 ImGui::SetNextWindowPos(ImGui::GetIO().MousePos, ImGuiCond_Once);
317 ImGui::SetNextWindowSize(ImVec2(0x100 + 1 * 16, 0x40 + 1 * 16),
318 ImGuiCond_Once);
319 ImGui::Begin(absl::StrFormat("##GfxEditPaletteChildWindow%d", id).c_str(),
320 &active, ImGuiWindowFlags_AlwaysUseWindowPadding);
321 current_sheet_ = id;
322 // ImVec2(0x100, 0x40),
323 current_sheet_canvas_.UpdateColorPainter(
324 GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->at(id), current_color_,
325 [&]() {
326
327 },
329 ImGui::End();
330
331 if (active == false) {
332 id_to_release = id;
333 }
334 }
335 if (id_to_release != -1) {
336 child_window_sheets_.erase(id_to_release);
337 }
338 }
339
340 return absl::OkStatus();
341}
342
344 if (rom()->is_loaded()) {
345 auto palette_group = *rom()->palette_group().get_group(
347 auto palette = palette_group.palette(edit_palette_index_);
348 gui::TextWithSeparators("ROM Palette");
349 ImGui::SetNextItemWidth(100.f);
350 ImGui::Combo("Palette Group", (int*)&edit_palette_group_name_index_,
352 IM_ARRAYSIZE(kPaletteGroupAddressesKeys));
353 ImGui::SetNextItemWidth(100.f);
354 gui::InputHex("Palette Group Index", &edit_palette_index_);
355
357 palette);
358
359 if (refresh_graphics_ && !open_sheets_.empty()) {
361 GraphicsSheetManager::GetInstance().mutable_gfx_sheets()
362 ->data()[current_sheet_]
363 .ApplyPaletteWithTransparent(palette, edit_palette_sub_index_));
365 &GraphicsSheetManager::GetInstance().mutable_gfx_sheets()->data()[current_sheet_]);
366 refresh_graphics_ = false;
367 }
368 }
369 return absl::OkStatus();
370}
371
373 TAB_ITEM("Player Animations")
374
375 if (ImGui::BeginTable("##PlayerAnimationTable", 3, kGfxEditTableFlags,
376 ImVec2(0, 0))) {
377 for (const auto& name : {"Canvas", "Animation Steps", "Properties"})
378 ImGui::TableSetupColumn(name);
379
380 ImGui::TableHeadersRow();
381
382 NEXT_COLUMN();
383 link_canvas_.DrawBackground();
384 link_canvas_.DrawGrid(16.0f);
385
386 int i = 0;
387 for (auto& link_sheet : link_sheets_) {
388 int x_offset = 0;
389 int y_offset = gfx::kTilesheetHeight * i * 4;
390 link_canvas_.DrawContextMenu(&link_sheet);
391 link_canvas_.DrawBitmap(link_sheet, x_offset, y_offset, 4);
392 i++;
393 }
394 link_canvas_.DrawOverlay();
395 link_canvas_.DrawGrid();
396
397 NEXT_COLUMN();
398 ImGui::Text("Placeholder");
399
400 NEXT_COLUMN();
401 if (ImGui::Button("Load Link Graphics (Experimental)")) {
402 if (rom()->is_loaded()) {
403 // Load Links graphics from the ROM
405
406 // Split it into the pose data frames
407 // Create an animation step display for the poses
408 // Allow the user to modify the frames used in an anim step
409 // LinkOAM_AnimationSteps:
410 // #_0D85FB
411 }
412 }
413 }
414 ImGui::EndTable();
415
417 return absl::OkStatus();
418}
419
421 TAB_ITEM("Prototype")
422
424
426 ImGui::Begin("Memory Editor", &open_memory_editor_);
428 ImGui::End();
429 }
430
431 constexpr ImGuiTableFlags kGfxEditFlags = ImGuiTableFlags_Reorderable |
432 ImGuiTableFlags_Resizable |
433 ImGuiTableFlags_SizingStretchSame;
434
435 BEGIN_TABLE("#gfxEditTable", 4, kGfxEditFlags)
436 SETUP_COLUMN("File Import (BIN, CGX, ROM)")
437 SETUP_COLUMN("Palette (COL)")
438 ImGui::TableSetupColumn("Tilemaps and Objects (SCR, PNL, OBJ)",
439 ImGuiTableColumnFlags_WidthFixed);
440 SETUP_COLUMN("Graphics Preview")
442 NEXT_COLUMN() {
447 }
448
450
453 scr_loaded_, false, 0);
455
457 if (super_donkey_) {
458 // TODO: Implement the Super Donkey 1 graphics decompression
459 // if (refresh_graphics_) {
460 // for (int i = 0; i < kNumGfxSheets; i++) {
461 // status_ = graphics_bin_[i].ApplyPalette(
462 // col_file_palette_group_[current_palette_index_]);
463 // Renderer::GetInstance().UpdateBitmap(&graphics_bin_[i]);
464 // }
465 // refresh_graphics_ = false;
466 // }
467 // Load the full graphics space from `super_donkey_1.bin`
468 // gui::GraphicsBinCanvasPipeline(0x100, 0x40, 0x20, num_sheets_to_load_, 3,
469 // super_donkey_, graphics_bin_);
470 } else if (cgx_loaded_ && col_file_) {
471 // Load the CGX graphics
473 cgx_loaded_, true, 5);
474 } else {
475 // Load the BIN/Clipboard Graphics
477 gfx_loaded_, true, 2);
478 }
479 END_TABLE()
480
482 return absl::OkStatus();
483}
484
486 static constexpr absl::string_view kGfxToolsetColumnNames[] = {
487 "#memoryEditor",
488 "##separator_gfx1",
489 };
490
491 if (ImGui::BeginTable("GraphicsToolset", 2, ImGuiTableFlags_SizingFixedFit,
492 ImVec2(0, 0))) {
493 for (const auto& name : kGfxToolsetColumnNames)
494 ImGui::TableSetupColumn(name.data());
495
496 TableNextColumn();
497 if (Button(ICON_MD_MEMORY)) {
498 if (!open_memory_editor_) {
499 open_memory_editor_ = true;
500 } else {
501 open_memory_editor_ = false;
502 }
503 }
504
505 TEXT_COLUMN("Open Memory Editor") // Separator
506
507 ImGui::EndTable();
508 }
509 return absl::OkStatus();
510}
511
513 gui::TextWithSeparators("Cgx Import");
514 InputInt("BPP", &current_bpp_);
515
516 InputText("##CGXFile", &cgx_file_name_);
517 SameLine();
518
519 if (ImGui::Button("Open CGX")) {
521 cgx_file_name_ = filename;
522 cgx_file_path_ = std::filesystem::absolute(filename).string();
523 is_open_ = true;
524 cgx_loaded_ = true;
525 }
526
527 if (ImGui::Button("Copy CGX Path")) {
528 ImGui::SetClipboardText(cgx_file_path_.c_str());
529 }
530
531 if (ImGui::Button("Load CGX Data")) {
534
535 cgx_bitmap_.Create(0x80, 0x200, 8, decoded_cgx_);
536 if (col_file_) {
537 cgx_bitmap_.ApplyPalette(decoded_col_);
539 }
540 }
541
542 return absl::OkStatus();
543}
544
546 InputText("##ScrFile", &scr_file_name_);
547
548 if (ImGui::Button("Open SCR")) {
550 scr_file_name_ = filename;
551 scr_file_path_ = std::filesystem::absolute(filename).string();
552 is_open_ = true;
553 scr_loaded_ = true;
554 }
555
556 InputInt("SCR Mod", &scr_mod_value_);
557
558 if (ImGui::Button("Load Scr Data")) {
559 status_ =
561
562 decoded_scr_data_.resize(0x100 * 0x100);
565
566 scr_bitmap_.Create(0x100, 0x100, 8, decoded_scr_data_);
567 if (scr_loaded_) {
568 scr_bitmap_.ApplyPalette(decoded_col_);
570 }
571 }
572
573 return absl::OkStatus();
574}
575
577 gui::TextWithSeparators("COL Import");
578 InputText("##ColFile", &col_file_name_);
579 SameLine();
580
581 if (ImGui::Button("Open COL")) {
583 col_file_name_ = filename;
584 col_file_path_ = std::filesystem::absolute(filename).string();
585 status_ = temp_rom_.LoadFromFile(col_file_path_,
586 /*z3_load=*/false);
587 auto col_data_ = gfx::GetColFileData(temp_rom_.mutable_data());
588 if (col_file_palette_group_.size() != 0) {
590 }
591 auto col_file_palette_group_status =
593 if (col_file_palette_group_status.ok()) {
594 col_file_palette_group_ = col_file_palette_group_status.value();
595 }
597
598 // gigaleak dev format based code
600 col_file_ = true;
601 is_open_ = true;
602 }
603 HOVER_HINT(".COL, .BAK");
604
605 if (ImGui::Button("Copy Col Path")) {
606 ImGui::SetClipboardText(col_file_path_.c_str());
607 }
608
609 if (rom()->is_loaded()) {
610 gui::TextWithSeparators("ROM Palette");
611 gui::InputHex("Palette Index", &current_palette_index_);
612 ImGui::Combo("Palette", &current_palette_, kPaletteGroupAddressesKeys,
613 IM_ARRAYSIZE(kPaletteGroupAddressesKeys));
614 }
615
616 if (col_file_palette_.size() != 0) {
619 }
620
621 return absl::OkStatus();
622}
623
625 gui::TextWithSeparators("OBJ Import");
626
627 InputText("##ObjFile", &obj_file_path_);
628 SameLine();
629
630 if (ImGui::Button("Open OBJ")) {
632 obj_file_path_ = std::filesystem::absolute(filename).string();
633 status_ = temp_rom_.LoadFromFile(obj_file_path_);
634 is_open_ = true;
635 obj_loaded_ = true;
636 }
637 HOVER_HINT(".OBJ, .BAK");
638
639 return absl::OkStatus();
640}
641
643 gui::TextWithSeparators("Tilemap Import");
644
645 InputText("##TMapFile", &tilemap_file_path_);
646 SameLine();
647
648 if (ImGui::Button("Open Tilemap")) {
650 tilemap_file_path_ = std::filesystem::absolute(filename).string();
653
654 // Extract the high and low bytes from the file.
655 auto decomp_sheet = gfx::lc_lz2::DecompressV2(tilemap_rom_.data(),
657 tilemap_loaded_ = true;
658 is_open_ = true;
659 }
660 HOVER_HINT(".DAT, .BIN, .HEX");
661
662 return absl::OkStatus();
663}
664
666 gui::TextWithSeparators("BIN Import");
667
668 InputText("##ROMFile", &file_path_);
669 SameLine();
670
671 if (ImGui::Button("Open BIN")) {
673 file_path_ = filename;
674 status_ = temp_rom_.LoadFromFile(file_path_);
675 is_open_ = true;
676 }
677 HOVER_HINT(".BIN, .HEX");
678
679 if (Button("Copy File Path")) {
680 ImGui::SetClipboardText(file_path_.c_str());
681 }
682
683 gui::InputHex("BIN Offset", &current_offset_);
684 gui::InputHex("BIN Size", &bin_size_);
685
686 if (Button("Decompress BIN")) {
687 if (file_path_.empty()) {
688 return absl::InvalidArgumentError(
689 "Please select a file before decompressing.");
690 }
692 }
693
694 return absl::OkStatus();
695}
696
698 gui::TextWithSeparators("Clipboard Import");
699 if (Button("Paste From Clipboard")) {
700 const char* text = ImGui::GetClipboardText();
701 if (text) {
702 const auto clipboard_data =
703 std::vector<uint8_t>(text, text + strlen(text));
704 ImGui::MemFree((void*)text);
705 status_ = temp_rom_.LoadFromData(clipboard_data);
706 is_open_ = true;
707 open_memory_editor_ = true;
708 }
709 }
712 gui::InputHex("Num Sheets", &num_sheets_to_load_);
713
714 if (Button("Decompress Clipboard Data")) {
715 if (temp_rom_.is_loaded()) {
716 status_ = DecompressImportData(0x40000);
717 } else {
718 status_ = absl::InvalidArgumentError(
719 "Please paste data into the clipboard before "
720 "decompressing.");
721 }
722 }
723
724 return absl::OkStatus();
725}
726
728 gui::TextWithSeparators("Experimental");
729 if (Button("Decompress Super Donkey Full")) {
730 if (file_path_.empty()) {
731 return absl::InvalidArgumentError(
732 "Please select `super_donkey_1.bin` before "
733 "importing.");
734 }
736 }
737 ImGui::SetItemTooltip(
738 "Requires `super_donkey_1.bin` to be imported under the "
739 "BIN import section.");
740 return absl::OkStatus();
741}
742
744 std::string title = "Memory Editor";
745 if (is_open_) {
746 static MemoryEditor mem_edit;
747 mem_edit.DrawWindow(title.c_str(), temp_rom_.mutable_data(),
748 temp_rom_.size());
749 }
750 return absl::OkStatus();
751}
752
755 temp_rom_.data(), current_offset_, size))
756
757 auto converted_sheet = gfx::SnesTo8bppSheet(import_data_, 3);
759 converted_sheet);
760
761 if (rom()->is_loaded()) {
762 auto palette_group = rom()->palette_group().overworld_animated;
763 z3_rom_palette_ = palette_group[current_palette_];
764 if (col_file_) {
765 status_ = bin_bitmap_.ApplyPalette(col_file_palette_);
766 } else {
767 status_ = bin_bitmap_.ApplyPalette(z3_rom_palette_);
768 }
769 }
770
772 gfx_loaded_ = true;
773
774 return absl::OkStatus();
775}
776
778 int i = 0;
779 for (const auto& offset : kSuperDonkeyTiles) {
780 int offset_value =
781 std::stoi(offset, nullptr, 16); // convert hex string to int
783 auto decompressed_data,
784 gfx::lc_lz2::DecompressV2(temp_rom_.data(), offset_value, 0x1000))
785 auto converted_sheet = gfx::SnesTo8bppSheet(decompressed_data, 3);
787 gfx::kTilesheetDepth, converted_sheet);
788 if (col_file_) {
789 status_ = gfx_sheets_[i].ApplyPalette(
791 } else {
792 // ROM palette
793
794 auto palette_group = rom()->palette_group().get_group(
796 z3_rom_palette_ = *palette_group->mutable_palette(current_palette_index_);
797 status_ = gfx_sheets_[i].ApplyPalette(z3_rom_palette_);
798 }
799
801 i++;
802 }
803
804 for (const auto& offset : kSuperDonkeySprites) {
805 int offset_value =
806 std::stoi(offset, nullptr, 16); // convert hex string to int
808 auto decompressed_data,
809 gfx::lc_lz2::DecompressV2(temp_rom_.data(), offset_value, 0x1000))
810 auto converted_sheet = gfx::SnesTo8bppSheet(decompressed_data, 3);
812 gfx::kTilesheetDepth, converted_sheet);
813 if (col_file_) {
814 status_ = gfx_sheets_[i].ApplyPalette(
816 } else {
817 // ROM palette
818 auto palette_group = rom()->palette_group().get_group(
820 z3_rom_palette_ = *palette_group->mutable_palette(current_palette_index_);
821 status_ = gfx_sheets_[i].ApplyPalette(z3_rom_palette_);
822 }
823
825 i++;
826 }
827 super_donkey_ = true;
829
830 return absl::OkStatus();
831}
832
833} // namespace editor
834} // namespace yaze
static GraphicsSheetManager & GetInstance()
Definition rom.h:271
std::array< gfx::Bitmap, kNumGfxSheets > & gfx_sheets()
Definition rom.h:277
auto rom()
Definition rom.h:383
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath.
void UpdateBitmap(gfx::Bitmap *bitmap)
Used to update a bitmap on the screen.
Definition renderer.h:55
void RenderBitmap(gfx::Bitmap *bitmap)
Used to render a bitmap to the screen.
Definition renderer.h:48
std::vector< uint8_t > scr_data_
std::array< gfx::Bitmap, kNumLinkSheets > link_sheets_
gfx::PaletteGroup col_file_palette_group_
std::vector< uint8_t > decoded_cgx_
std::set< uint16_t > child_window_sheets_
std::array< gfx::Bitmap, kNumGfxSheets > gfx_sheets_
std::vector< uint8_t > cgx_data_
std::vector< uint8_t > import_data_
std::vector< SDL_Color > decoded_col_
std::set< uint16_t > open_sheets_
absl::Status Update() override
std::vector< uint8_t > extra_cgx_data_
std::vector< uint8_t > decoded_scr_data_
std::stack< uint16_t > release_queue_
gui::GfxSheetAssetBrowser asset_browser_
absl::Status DecompressImportData(int size)
static Renderer & GetInstance()
Definition renderer.h:26
Represents a bitmap image.
Definition bitmap.h:66
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
#define ICON_MD_MEMORY
Definition icons.h:1193
#define ICON_MD_DRAW
Definition icons.h:623
#define ICON_MD_ZOOM_OUT
Definition icons.h:2191
#define ICON_MD_FORMAT_COLOR_FILL
Definition icons.h:828
#define ICON_MD_CONTENT_PASTE
Definition icons.h:465
#define ICON_MD_ADD
Definition icons.h:84
#define ICON_MD_ZOOM_IN
Definition icons.h:2189
#define ICON_MD_SELECT_ALL
Definition icons.h:1678
#define ICON_MD_CONTENT_COPY
Definition icons.h:463
#define SETUP_COLUMN(l)
Definition macro.h:21
#define END_TABLE()
Definition macro.h:29
#define TABLE_HEADERS()
Definition macro.h:23
#define BEGIN_TABLE(l, n, f)
Definition macro.h:20
#define RETURN_IF_ERROR(expression)
Definition macro.h:62
#define END_TAB_ITEM()
Definition macro.h:5
#define NEXT_COLUMN()
Definition macro.h:27
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Definition macro.h:70
#define CLEAR_AND_RETURN_STATUS(status)
Definition macro.h:105
#define TEXT_COLUMN(w)
Definition macro.h:16
#define TAB_ITEM(w)
Definition macro.h:4
#define HOVER_HINT(string)
Definition macro.h:33
void GetImageFromClipboard(std::vector< uint8_t > &data, int &width, int &height)
Definition clipboard.cc:10
void CopyImageToClipboard(const std::vector< uint8_t > &data)
Definition clipboard.cc:9
Editors are the view controllers for the application.
const std::string kSuperDonkeySprites[]
constexpr ImGuiTableFlags kGfxEditTableFlags
const std::string kSuperDonkeyTiles[]
constexpr int kNintendoMode1
Definition compression.h:53
absl::StatusOr< std::vector< uint8_t > > DecompressV2(const uint8_t *data, int offset, int size, int mode)
Decompresses a buffer of data using the LC_LZ2 algorithm.
absl::Status LoadScr(std::string_view filename, uint8_t input_value, std::vector< uint8_t > &map_data)
Load Scr file (screen data)
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)
absl::Status DrawScrWithCgx(uint8_t bpp, std::vector< uint8_t > &map_data, std::vector< uint8_t > &map_bitmap_data, std::vector< uint8_t > &cgx_loaded)
Draw screen tilemap with graphical data.
std::vector< SDL_Color > DecodeColFile(const std::string_view filename)
Decode color file.
constexpr int kTilesheetHeight
Definition snes_tile.h:16
constexpr int kTilesheetWidth
Definition snes_tile.h:15
constexpr const char * kPaletteGroupAddressesKeys[]
constexpr int kTilesheetDepth
Definition snes_tile.h:17
absl::StatusOr< PaletteGroup > CreatePaletteGroupFromColFile(std::vector< SnesColor > &palette_rows)
std::vector< SnesColor > GetColFileData(uint8_t *data)
Definition snes_color.cc:89
std::vector< uint8_t > SnesTo8bppSheet(const std::vector< uint8_t > &sheet, int bpp, int num_sheets)
Definition snes_tile.cc:151
void BitmapCanvasPipeline(gui::Canvas &canvas, const gfx::Bitmap &bitmap, int width, int height, int tile_size, bool is_loaded, bool scrollbar, int canvas_id)
Definition canvas.cc:831
bool InputHex(const char *label, uint64_t *data)
Definition input.cc:134
void SelectablePalettePipeline(uint64_t &palette_id, bool &refresh_graphics, gfx::SnesPalette &palette)
Definition color.cc:123
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
Definition input.cc:167
void TextWithSeparators(const absl::string_view &text)
Definition style.cc:746
Main namespace for the application.
Definition controller.cc:18
absl::StatusOr< std::array< gfx::Bitmap, kNumLinkSheets > > LoadLinkGraphics(const Rom &rom)
Loads the players 4bpp graphics sheet from Rom data.
Definition rom.cc:58
constexpr uint32_t kNumGfxSheets
Definition rom.h:30