Add SelectablePalettePipeline for updating palette

This commit is contained in:
Justin Scofield
2023-08-03 21:09:27 -04:00
parent d2789ff7b6
commit 7d0b09a589
11 changed files with 116 additions and 37 deletions

View File

@@ -19,6 +19,33 @@ namespace yaze {
namespace app {
namespace core {
void SelectablePalettePipeline(uint64_t& palette_id, bool& refresh_graphics,
gfx::SNESPalette& palette) {
if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)100);
ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
ImGui::BeginGroup(); // Lock X position
ImGui::Text("Palette");
for (int n = 0; n < palette.size(); n++) {
ImGui::PushID(n);
if ((n % 8) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
if (ImGui::ColorButton("##palette", palette[n].RGB(),
ImGuiColorEditFlags_NoAlpha |
ImGuiColorEditFlags_NoPicker |
ImGuiColorEditFlags_NoTooltip,
ImVec2(20, 20))) {
palette_id = n / 8;
refresh_graphics = true;
}
ImGui::PopID();
}
ImGui::EndGroup();
}
ImGui::EndChild();
}
void GraphicsBinCanvasPipeline(int width, int height, int tile_size,
int num_sheets_to_load, int canvas_id,
bool is_loaded, gfx::BitmapTable& graphics_bin) {
@@ -56,21 +83,29 @@ void ButtonPipe(absl::string_view button_text, std::function<void()> callback) {
}
}
void BitmapCanvasPipeline(int width, int height, int tile_size, int canvas_id,
bool is_loaded, gfx::Bitmap& bitmap) {
void BitmapCanvasPipeline(int width, int height, int tile_size, bool is_loaded,
gfx::Bitmap& bitmap, bool scrollbar, int canvas_id) {
gui::Canvas canvas;
if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)canvas_id);
ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
auto draw_canvas = [&]() {
canvas.DrawBackground(ImVec2(width + 1, height + 1));
canvas.DrawContextMenu();
canvas.DrawBitmap(bitmap, 2, is_loaded);
canvas.DrawTileSelector(tile_size);
canvas.DrawGrid(tile_size);
canvas.DrawOverlay();
};
if (scrollbar) {
if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)canvas_id);
ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
draw_canvas();
}
ImGui::EndChild();
} else {
draw_canvas();
}
ImGui::EndChild();
}
void BuildAndRenderBitmapPipeline(int width, int height, int depth, Bytes data,

View File

@@ -19,14 +19,17 @@ namespace yaze {
namespace app {
namespace core {
void SelectablePalettePipeline(uint64_t& palette_id, bool& refresh_graphics,
gfx::SNESPalette& palette);
void GraphicsBinCanvasPipeline(int width, int height, int tile_size,
int num_sheets_to_load, int canvas_id,
bool is_loaded, gfx::BitmapTable& graphics_bin);
void ButtonPipe(absl::string_view button_text, std::function<void()> callback);
void BitmapCanvasPipeline(int width, int height, int tile_size, int canvas_id,
bool is_loaded, gfx::Bitmap& bitmap);
void BitmapCanvasPipeline(int width, int height, int tile_size, bool is_loaded,
gfx::Bitmap& bitmap, bool scrollbar, int canvas_id);
void BuildAndRenderBitmapPipeline(int width, int height, int depth, Bytes data,
ROM& z3_rom, gfx::Bitmap& bitmap,

View File

@@ -33,7 +33,8 @@ absl::Status GraphicsEditor::Update() {
BEGIN_TABLE("#gfxEditTable", 4, kGfxEditFlags)
SETUP_COLUMN("Graphics (BIN, CGX, SCR)")
SETUP_COLUMN("Palette (COL)")
SETUP_COLUMN("Maps and Animations (SCR, PNL)")
ImGui::TableSetupColumn("Maps and Animations (SCR, PNL)",
ImGuiTableColumnFlags_WidthFixed);
SETUP_COLUMN("Preview")
TABLE_HEADERS()
NEXT_COLUMN()
@@ -47,15 +48,30 @@ absl::Status GraphicsEditor::Update() {
status_ = DrawPaletteControls();
NEXT_COLUMN()
core::BitmapCanvasPipeline(0x200, 0x200, 0x20, 6, scr_loaded_, cgx_bitmap_);
core::BitmapCanvasPipeline(0x200, 0x200, 0x20, scr_loaded_, cgx_bitmap_,
false, 0);
NEXT_COLUMN()
if (super_donkey_) {
status_ = DrawGraphicsBin();
if (refresh_graphics_) {
for (int i = 0; i < graphics_bin_.size(); i++) {
graphics_bin_[i].ApplyPalette(
col_file_palette_group_[current_palette_index_]);
rom_.UpdateBitmap(&graphics_bin_[i]);
}
refresh_graphics_ = false;
}
// Load the full graphics space from `super_donkey_1.bin`
core::GraphicsBinCanvasPipeline(0x100, 0x40, 0x20, num_sheets_to_load_, 3,
super_donkey_, graphics_bin_);
} else if (cgx_loaded_ && col_file_) {
core::BitmapCanvasPipeline(0x100, 16384, 0x20, 5, cgx_loaded_, cgx_bitmap_);
// Load the CGX graphics
core::BitmapCanvasPipeline(0x100, 16384, 0x20, cgx_loaded_, cgx_bitmap_,
true, 5);
} else {
core::BitmapCanvasPipeline(0x100, 16384, 0x20, 2, gfx_loaded_, bitmap_);
// Load the BIN/Clipboard Graphics
core::BitmapCanvasPipeline(0x100, 16384, 0x20, gfx_loaded_, bitmap_, true,
2);
}
END_TABLE()
@@ -170,15 +186,7 @@ absl::Status GraphicsEditor::DrawPaletteControls() {
if (col_file_palette_group_.size() != 0) {
col_file_palette_group_.Clear();
}
for (int i = 0; i < col_data_.size(); i += 8) {
// Extract 8 colors from the col_data_ and make them into a palette
gfx::SNESPalette palette;
for (int j = 0; j < 8; j++) {
palette.AddColor(col_data_[i + j]);
}
// color.AddColor()
col_file_palette_group_.AddPalette(palette);
}
col_file_palette_group_ = gfx::CreatePaletteGroupFromColFile(col_data_);
col_file_palette_ = gfx::SNESPalette(col_data_);
col_file_ = true;
is_open_ = true;
@@ -195,7 +203,8 @@ absl::Status GraphicsEditor::DrawPaletteControls() {
}
if (col_file_palette_.size() != 0) {
palette_editor_.DrawPortablePalette(col_file_palette_);
core::SelectablePalettePipeline(current_palette_index_, refresh_graphics_,
col_file_palette_);
}
return absl::OkStatus();
@@ -257,12 +266,6 @@ absl::Status GraphicsEditor::DrawMemoryEditor() {
return absl::OkStatus();
}
absl::Status GraphicsEditor::DrawGraphicsBin() {
core::GraphicsBinCanvasPipeline(0x100, 0x40, 0x20, num_sheets_to_load_, 3,
super_donkey_, graphics_bin_);
return absl::OkStatus();
}
absl::Status GraphicsEditor::DecompressImportData(int size) {
ASSIGN_OR_RETURN(import_data_, gfx::lc_lz2::DecompressV2(
temp_rom_.data(), current_offset_, size))
@@ -298,7 +301,7 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() {
auto converted_sheet = gfx::SnesTo8bppSheet(decompressed_data, 3);
graphics_bin_[i] =
gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
core::kTilesheetDepth, converted_sheet.data(), 0x1000);
core::kTilesheetDepth, converted_sheet);
if (col_file_) {
graphics_bin_[i].ApplyPalette(
col_file_palette_group_[current_palette_index_]);
@@ -323,7 +326,7 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() {
auto converted_sheet = gfx::SnesTo8bppSheet(decompressed_data, 3);
graphics_bin_[i] =
gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
core::kTilesheetDepth, converted_sheet.data(), 0x1000);
core::kTilesheetDepth, converted_sheet);
if (col_file_) {
graphics_bin_[i].ApplyPalette(
col_file_palette_group_[current_palette_index_]);

View File

@@ -73,7 +73,6 @@ class GraphicsEditor {
absl::Status DrawClipboardImport();
absl::Status DrawExperimentalFeatures();
absl::Status DrawMemoryEditor();
absl::Status DrawGraphicsBin();
absl::Status DecompressImportData(int size);
@@ -91,6 +90,7 @@ class GraphicsEditor {
uint64_t clipboard_offset_ = 0;
uint64_t clipboard_size_ = 0;
bool refresh_graphics_ = false;
bool open_memory_editor_ = false;
bool gfx_loaded_ = false;
bool is_open_ = false;

View File

@@ -301,8 +301,14 @@ void MasterEditor::DrawHelpMenu() {
if (open_rom_help) ImGui::OpenPopup("Open a ROM");
if (ImGui::BeginPopupModal("Open a ROM", nullptr,
ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text("File -> Open");
ImGui::Text("Select a ROM file to open");
ImGui::Text("Supported ROMs:");
ImGui::Text("The Legend of Zelda: A Link to the Past");
ImGui::Text("US Version 1.0");
ImGui::Separator();
ImGui::Text("Must remove header before opening");
ImGui::Text("Header is 0x200 bytes of data at the beginning of the ROM");
if (ImGui::Button("Close", gui::kDefaultModalSize)) {
open_rom_help = false;

View File

@@ -263,8 +263,8 @@ void OverworldEditor::DrawTileSelector() {
if (ImGui::BeginTabBar(kTileSelectorTab.data(),
ImGuiTabBarFlags_FittingPolicyScroll)) {
if (ImGui::BeginTabItem("Tile16")) {
core::BitmapCanvasPipeline(0x100, (8192 * 2), 0x20, 1,
map_blockset_loaded_, tile16_blockset_bmp_);
core::BitmapCanvasPipeline(0x100, (8192 * 2), 0x20, map_blockset_loaded_,
tile16_blockset_bmp_, true, 1);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Tile8")) {
@@ -277,8 +277,8 @@ void OverworldEditor::DrawTileSelector() {
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Area Graphics")) {
core::BitmapCanvasPipeline(256, 0x10 * 0x40, 0x20, 3,
overworld_.isLoaded(), current_gfx_bmp_);
core::BitmapCanvasPipeline(256, 0x10 * 0x40, 0x20, overworld_.isLoaded(),
current_gfx_bmp_, true, 3);
ImGui::EndTabItem();
}
ImGui::EndTabBar();

View File

@@ -37,6 +37,10 @@ Bitmap::Bitmap(int width, int height, int depth, uchar *data, int data_size) {
Create(width, height, depth, data, data_size);
}
Bitmap::Bitmap(int width, int height, int depth, Bytes data) {
Create(width, height, depth, data);
}
// Pass raw pixel data directly to the surface
void Bitmap::Create(int width, int height, int depth, uchar *data) {
active_ = true;
@@ -112,9 +116,18 @@ void Bitmap::CreateTexture(std::shared_ptr<SDL_Renderer> renderer) {
SDL_Texture_Deleter{}};
}
void Bitmap::UpdateTexture(std::shared_ptr<SDL_Renderer> renderer) {
SDL_DestroyTexture(texture_.get());
texture_ = nullptr;
texture_ = std::shared_ptr<SDL_Texture>{
SDL_CreateTextureFromSurface(renderer.get(), surface_.get()),
SDL_Texture_Deleter{}};
}
// Convert SNESPalette to SDL_Palette for surface.
void Bitmap::ApplyPalette(const SNESPalette &palette) {
palette_ = palette;
SDL_UnlockSurface(surface_.get());
for (int i = 0; i < palette.size_; ++i) {
if (palette.GetColor(i).transparent) {
surface_->format->palette->colors[i].r = 0;
@@ -128,6 +141,7 @@ void Bitmap::ApplyPalette(const SNESPalette &palette) {
surface_->format->palette->colors[i].a = palette.GetColor(i).rgb.w;
}
}
SDL_LockSurface(surface_.get());
}
} // namespace gfx

View File

@@ -22,6 +22,7 @@ class Bitmap {
Bitmap(int width, int height, int depth, uchar *data);
Bitmap(int width, int height, int depth, int data_size);
Bitmap(int width, int height, int depth, uchar *data, int data_size);
Bitmap(int width, int height, int depth, Bytes data);
void Create(int width, int height, int depth, uchar *data);
void Create(int width, int height, int depth, int data_size);
@@ -31,6 +32,7 @@ class Bitmap {
void Apply(Bytes data);
void CreateTexture(std::shared_ptr<SDL_Renderer> renderer);
void UpdateTexture(std::shared_ptr<SDL_Renderer> renderer);
void ApplyPalette(const SNESPalette &palette);

View File

@@ -214,6 +214,20 @@ SDL_Palette* SNESPalette::GetSDL_Palette() {
PaletteGroup::PaletteGroup(uint8_t mSize) : size_(mSize) {}
PaletteGroup CreatePaletteGroupFromColFile(
std::vector<SNESColor>& palette_rows) {
PaletteGroup toret;
for (int i = 0; i < palette_rows.size(); i += 8) {
SNESPalette palette;
for (int j = 0; j < 8; j++) {
palette.AddColor(palette_rows[i + j]);
}
toret.AddPalette(palette);
}
return toret;
}
} // namespace gfx
} // namespace app
} // namespace yaze

View File

@@ -156,6 +156,8 @@ struct PaletteGroup {
std::vector<SNESPalette> palettes;
};
PaletteGroup CreatePaletteGroupFromColFile(std::vector<SNESColor>& colors);
} // namespace gfx
} // namespace app
} // namespace yaze

View File

@@ -17,7 +17,7 @@ void ColorsYaze() {
ImVec4 *colors = style->Colors;
style->WindowPadding = ImVec2(10.f, 10.f);
style->FramePadding = ImVec2(10.f, 3.f);
style->FramePadding = ImVec2(10.f, 2.f);
style->CellPadding = ImVec2(4.f, 5.f);
style->ItemSpacing = ImVec2(10.f, 5.f);
style->ItemInnerSpacing = ImVec2(5.f, 5.f);