3#include "absl/status/status.h"
4#include "absl/strings/str_cat.h"
12#include "imgui/imgui.h"
18using ImGui::BeginChild;
19using ImGui::BeginCombo;
20using ImGui::BeginGroup;
21using ImGui::BeginTabBar;
22using ImGui::BeginTabItem;
23using ImGui::BeginTable;
27using ImGui::EndTabBar;
28using ImGui::EndTabItem;
30using ImGui::GetContentRegionAvail;
32using ImGui::IsItemClicked;
36using ImGui::Selectable;
37using ImGui::Separator;
38using ImGui::SetNextItemWidth;
39using ImGui::SliderFloat;
40using ImGui::TableHeadersRow;
41using ImGui::TableNextColumn;
42using ImGui::TableNextRow;
43using ImGui::TableSetupColumn;
46using gfx::kPaletteGroupNames;
55constexpr int kTileSize = 16;
59 float scale = kDefaultScale) {
69 canvas.
DrawBackground(ImVec2(display_width + 1, display_height + 1));
76 canvas.
DrawGrid(
static_cast<int>(8 * scale));
89 if (BeginTabBar(
"##GfxGroupEditorTabs")) {
90 if (BeginTabItem(
"Blocksets")) {
92 static_cast<uint8_t
>(0x24));
100 if (BeginTabItem(
"Roomsets")) {
102 static_cast<uint8_t
>(81));
110 if (BeginTabItem(
"Spritesets")) {
112 static_cast<uint8_t
>(143));
123 return absl::OkStatus();
128 Text(
"No game data loaded");
132 PushID(
"BlocksetViewer");
134 if (BeginTable(
"##BlocksetTable", sheet_only ? 1 : 2,
135 ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable,
138 TableSetupColumn(
"Inputs", ImGuiTableColumnFlags_WidthStretch,
139 GetContentRegionAvail().x);
142 TableSetupColumn(
"Sheets", ImGuiTableColumnFlags_WidthFixed,
143 kSheetDisplayWidth + 16);
150 for (
int idx = 0; idx < 8; idx++) {
151 SetNextItemWidth(100.f);
153 (
"Slot " + std::to_string(idx)).c_str(),
161 for (
int idx = 0; idx < 8; idx++) {
184 Text(
"No game data loaded");
188 PushID(
"RoomsetViewer");
189 Text(
"Roomsets overwrite slots 4-7 of the main blockset");
191 if (BeginTable(
"##RoomsTable", 3,
192 ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable,
194 TableSetupColumn(
"List", ImGuiTableColumnFlags_WidthFixed, 120);
195 TableSetupColumn(
"Inputs", ImGuiTableColumnFlags_WidthStretch,
196 GetContentRegionAvail().x);
197 TableSetupColumn(
"Sheets", ImGuiTableColumnFlags_WidthFixed,
198 kSheetDisplayWidth + 16);
204 if (BeginChild(
"##RoomsetListChild", ImVec2(0, 300))) {
205 for (
int idx = 0; idx < 0x51; idx++) {
207 std::string roomset_label = absl::StrFormat(
"0x%02X", idx);
209 if (Selectable(roomset_label.c_str(), is_selected)) {
220 Text(
"Sheet IDs (overwrites slots 4-7):");
221 for (
int idx = 0; idx < 4; idx++) {
222 SetNextItemWidth(100.f);
224 (
"Slot " + std::to_string(idx + 4)).c_str(),
232 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;
352 if (BeginCombo(
"##PaletteCategory",
354 for (
int cat = 0; cat < kNumPaletteCategories; cat++) {
357 if (Selectable(gfx::kPaletteCategoryNames[category].data(), is_selected)) {
363 ImGui::SetItemDefaultFocus();
370 SetNextItemWidth(80.f);
377 if (ImGui::IsItemHovered()) {
378 ImGui::SetTooltip(
"Apply selected palette to sheet previews");
396 case PaletteCategory::kSword:
399 case PaletteCategory::kShield:
402 case PaletteCategory::kClothes:
405 case PaletteCategory::kWorldColors:
409 case PaletteCategory::kAreaColors:
413 case PaletteCategory::kGlobalSprites:
417 case PaletteCategory::kSpritesAux1:
421 case PaletteCategory::kSpritesAux2:
425 case PaletteCategory::kSpritesAux3:
429 case PaletteCategory::kDungeons:
433 case PaletteCategory::kWorldMap:
434 case PaletteCategory::kDungeonMap:
438 case PaletteCategory::kTriforce:
439 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