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