3#include "absl/status/status.h"
4#include "absl/strings/str_cat.h"
5#include "absl/strings/str_format.h"
13#include "imgui/imgui.h"
19using ImGui::BeginChild;
20using ImGui::BeginCombo;
21using ImGui::BeginGroup;
22using ImGui::BeginTabBar;
23using ImGui::BeginTabItem;
24using ImGui::BeginTable;
28using ImGui::EndTabBar;
29using ImGui::EndTabItem;
31using ImGui::GetContentRegionAvail;
33using ImGui::IsItemClicked;
37using ImGui::Selectable;
38using ImGui::Separator;
39using ImGui::SetNextItemWidth;
40using ImGui::SliderFloat;
41using ImGui::TableHeadersRow;
42using ImGui::TableNextColumn;
43using ImGui::TableNextRow;
44using ImGui::TableSetupColumn;
47using gfx::kPaletteGroupNames;
56constexpr int kTileSize = 16;
60 float scale = kDefaultScale) {
68 canvas.
DrawBackground(ImVec2(display_width + 1, display_height + 1));
75 canvas.
DrawGrid(
static_cast<int>(8 * scale));
88 if (BeginTabBar(
"##GfxGroupEditorTabs")) {
89 if (BeginTabItem(
"Blocksets")) {
91 static_cast<uint8_t
>(0x24));
99 if (BeginTabItem(
"Roomsets")) {
101 static_cast<uint8_t
>(81));
109 if (BeginTabItem(
"Spritesets")) {
111 static_cast<uint8_t
>(143));
122 return absl::OkStatus();
127 Text(
"No game data loaded");
131 PushID(
"BlocksetViewer");
133 if (BeginTable(
"##BlocksetTable", sheet_only ? 1 : 2,
134 ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable,
137 TableSetupColumn(
"Inputs", ImGuiTableColumnFlags_WidthStretch,
138 GetContentRegionAvail().x);
141 TableSetupColumn(
"Sheets", ImGuiTableColumnFlags_WidthFixed,
142 kSheetDisplayWidth + 16);
149 for (
int idx = 0; idx < 8; idx++) {
150 SetNextItemWidth(100.f);
152 (
"Slot " + std::to_string(idx)).c_str(),
160 for (
int idx = 0; idx < 8; idx++) {
183 Text(
"No game data loaded");
187 PushID(
"RoomsetViewer");
188 Text(
"Roomsets overwrite slots 4-7 of the main blockset");
190 if (BeginTable(
"##RoomsTable", 3,
191 ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable,
193 TableSetupColumn(
"List", ImGuiTableColumnFlags_WidthFixed, 120);
194 TableSetupColumn(
"Inputs", ImGuiTableColumnFlags_WidthStretch,
195 GetContentRegionAvail().x);
196 TableSetupColumn(
"Sheets", ImGuiTableColumnFlags_WidthFixed,
197 kSheetDisplayWidth + 16);
203 if (BeginChild(
"##RoomsetListChild", ImVec2(0, 300))) {
204 for (
int idx = 0; idx < 0x51; idx++) {
206 std::string roomset_label = absl::StrFormat(
"0x%02X", idx);
208 if (Selectable(roomset_label.c_str(), is_selected)) {
219 Text(
"Sheet IDs (overwrites slots 4-7):");
220 for (
int idx = 0; idx < 4; idx++) {
221 SetNextItemWidth(100.f);
223 (
"Slot " + std::to_string(idx + 4)).c_str(),
231 for (
int idx = 0; idx < 4; idx++) {
255 Text(
"No game data loaded");
259 PushID(
"SpritesetViewer");
261 if (BeginTable(
"##SpritesTable", sheet_only ? 1 : 2,
262 ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable,
265 TableSetupColumn(
"Inputs", ImGuiTableColumnFlags_WidthStretch,
266 GetContentRegionAvail().x);
268 TableSetupColumn(
"Sheets", ImGuiTableColumnFlags_WidthFixed,
269 kSheetDisplayWidth + 16);
276 Text(
"Sprite sheet IDs (base 115+):");
277 for (
int idx = 0; idx < 4; idx++) {
278 SetNextItemWidth(100.f);
280 (
"Slot " + std::to_string(idx)).c_str(),
288 for (
int idx = 0; idx < 4; idx++) {
290 int sheet_id = 115 + sheet_offset;
313 if (palette.
empty()) {
316 for (
size_t color_idx = 0; color_idx < palette.
size(); color_idx++) {
317 PushID(
static_cast<int>(color_idx));
318 if ((color_idx % 8) != 0) {
319 SameLine(0.0f, GetStyle().ItemSpacing.y);
324 ImGuiColorEditFlags_NoAlpha |
325 ImGuiColorEditFlags_NoPicker |
326 ImGuiColorEditFlags_NoTooltip);
341 SetNextItemWidth(100.f);
342 SliderFloat(
"##ViewScale", &
view_scale_, 1.0f, 4.0f,
"%.1fx");
348 SetNextItemWidth(150.f);
351 static constexpr int kNumPaletteCategories = 14;
355 for (
int cat = 0; cat < kNumPaletteCategories; cat++) {
358 if (Selectable(gfx::kPaletteCategoryNames[category].data(),
365 ImGui::SetItemDefaultFocus();
372 SetNextItemWidth(80.f);
379 if (ImGui::IsItemHovered()) {
380 ImGui::SetTooltip(
"Apply selected palette to sheet previews");
398 case PaletteCategory::kSword:
401 case PaletteCategory::kShield:
405 case PaletteCategory::kClothes:
408 case PaletteCategory::kWorldColors:
412 case PaletteCategory::kAreaColors:
416 case PaletteCategory::kGlobalSprites:
420 case PaletteCategory::kSpritesAux1:
424 case PaletteCategory::kSpritesAux2:
428 case PaletteCategory::kSpritesAux3:
432 case PaletteCategory::kDungeons:
436 case PaletteCategory::kWorldMap:
437 case PaletteCategory::kDungeonMap:
441 case PaletteCategory::kTriforce:
442 case PaletteCategory::kCrystal:
project::ResourceLabelManager * resource_label()
uint8_t selected_blockset_
uint8_t selected_spriteset_
uint8_t selected_palette_index_
std::array< gui::Canvas, 8 > blockset_canvases_
zelda3::GameData * game_data() const
gfx::PaletteCategory selected_palette_category_
std::array< gui::Canvas, 4 > roomset_canvases_
void UpdateCurrentPalette()
gfx::SnesPalette * current_palette_
uint8_t selected_roomset_
void DrawSpritesetViewer(bool sheet_only=false)
std::array< gui::Canvas, 4 > spriteset_canvases_
void DrawPaletteControls()
void DrawBlocksetViewer(bool sheet_only=false)
auto mutable_gfx_sheets()
Get mutable reference to all graphics sheets.
void NotifySheetModified(int sheet_index)
Notify Arena that a graphics sheet has been modified.
Represents a bitmap image optimized for SNES ROM hacking.
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
Modern, robust canvas for drawing and manipulating graphics.
void DrawBitmap(Bitmap &bitmap, int border_offset, float scale)
void DrawBackground(ImVec2 canvas_size=ImVec2(0, 0))
void DrawGrid(float grid_step=64.0f, int tile_id_offset=8)
constexpr int kSheetDisplayWidth
void DrawScaledSheet(gui::Canvas &canvas, gfx::Bitmap &sheet, int unique_id, float scale=kDefaultScale)
constexpr int kSheetDisplayHeight
void DrawPaletteFromPaletteGroup(gfx::SnesPalette &palette)
constexpr float kDefaultScale
PaletteCategory
Categories for organizing palette groups in the UI.
constexpr int kTilesheetHeight
constexpr int kTilesheetWidth
IMGUI_API bool SnesColorButton(absl::string_view id, gfx::SnesColor &color, ImGuiColorEditFlags flags, const ImVec2 &size_arg)
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
void SelectableLabelWithNameEdit(bool selected, const std::string &type, const std::string &key, const std::string &defaultValue)
std::array< std::array< uint8_t, 4 >, kNumSpritesets > spriteset_ids
std::array< std::array< uint8_t, 4 >, kNumRoomBlocksets > room_blockset_ids
gfx::PaletteGroupMap palette_groups
std::array< std::array< uint8_t, 8 >, kNumMainBlocksets > main_blockset_ids