yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
graphics_palette_preview.cc
Go to the documentation of this file.
2
3#include <algorithm>
4#include <vector>
5
10#include "zelda3/game_data.h"
11
12namespace yaze::editor {
13
14absl::StatusOr<GraphicsPalettePreview> ResolveGraphicsPreviewPalette(
15 zelda3::GameData& data, const GraphicsPaletteSelection& selection) {
16 auto* group = data.palette_groups.get_group(selection.group);
17 if (!group || selection.palette < 0 || selection.palette >= group->size()) {
18 return absl::InvalidArgumentError("Preview palette is unavailable");
19 }
20 const auto& palette = group->palette_ref(selection.palette);
21 const auto layout =
22 internal::GetPaletteRowLayout(selection.group, palette.size());
23 const int rows =
24 internal::GetPaletteRowCount(palette.size(), layout.colors_per_row);
25 if (selection.row < 0 || selection.row >= rows) {
26 return absl::InvalidArgumentError("Preview palette row is unavailable");
27 }
28 const size_t offset = selection.row * layout.colors_per_row +
29 (layout.has_explicit_transparent ? 1 : 0);
30 const size_t length = std::min<size_t>(
31 7, std::min<size_t>(
32 layout.colors_per_row - (layout.has_explicit_transparent ? 1 : 0),
33 palette.size() - offset));
34 std::vector<gfx::SnesColor> colors(8, gfx::SnesColor(uint16_t{0}));
35 colors[0].set_transparent(true);
36 for (size_t i = 0; i < length; ++i) {
37 colors[i + 1] = palette[offset + i];
38 colors[i + 1].set_transparent(false);
39 }
41 static_cast<int>(group->size()), rows};
42}
43
45 GraphicsEditorState& state, uint16_t sheet,
46 std::optional<GraphicsPaletteSelection> selection) {
47 auto& arena = gfx::Arena::Get();
48 if (!state.game_data || arena.gfx_sheets_owner() != state.game_data ||
49 sheet >= arena.gfx_sheets().size()) {
50 return absl::FailedPreconditionError("This ROM's graphics are not active");
51 }
52 auto& bitmap = arena.mutable_gfx_sheets()->at(sheet);
53 const auto* current = platform::GetSurfacePalette(bitmap.surface());
54 if (!bitmap.is_active() || !current) {
55 return absl::FailedPreconditionError("This sheet has no display palette");
56 }
57
58 std::vector<SDL_Color> colors;
59 if (selection) {
60 const auto resolved =
61 ResolveGraphicsPreviewPalette(*state.game_data, *selection);
62 if (!resolved.ok()) {
63 return resolved.status();
64 }
65 for (size_t i = 0; i < resolved->colors.size(); ++i) {
66 const auto rgb = resolved->colors[i].rgb();
67 colors.push_back({static_cast<Uint8>(rgb.x), static_cast<Uint8>(rgb.y),
68 static_cast<Uint8>(rgb.z),
69 static_cast<Uint8>(i == 0 ? 0 : 255)});
70 }
71 } else {
72 const auto* loaded = platform::GetSurfacePalette(
73 state.game_data->gfx_bitmaps[sheet].surface());
74 if (!loaded) {
75 return absl::FailedPreconditionError("Loaded colors are unavailable");
76 }
77 colors.assign(loaded->colors,
78 loaded->colors + std::min(8, loaded->ncolors));
79 }
80 bool changed = current->ncolors < static_cast<int>(colors.size());
81 for (size_t i = 0; !changed && i < colors.size(); ++i) {
82 const auto& a = colors[i];
83 const auto& b = current->colors[i];
84 changed = a.r != b.r || a.g != b.g || a.b != b.b || a.a != b.a;
85 }
86 if (changed) {
87 bitmap.SetPalette(colors);
88 arena.NotifySheetModified(sheet);
89 }
90 if (selection) {
91 state.preview_palettes[sheet] = std::move(*selection);
92 } else {
93 state.preview_palettes.erase(sheet);
94 }
95 return absl::OkStatus();
96}
97
99 auto& manager = gfx::PaletteManager::Get();
100 if (manager.IsManaging(state.game_data) && state.source_context &&
101 state.source_context->owner == state.game_data) {
102 auto& context = *state.source_context;
103 const auto revision = manager.ColorRevision(state.game_data);
104 if (context.refresh_palettes && context.palette_revision != revision) {
105 const auto status = context.refresh_palettes(context);
106 context.palette_error = status.ok() ? "" : std::string(status.message());
107 context.palette_revision = revision;
108 }
109 }
110 for (const auto& [sheet, selection] : state.preview_palettes) {
111 SetGraphicsPreviewPalette(state, sheet, selection).IgnoreError();
112 }
113}
114
115} // namespace yaze::editor
Shared state between GraphicsEditor panel components.
std::map< uint16_t, GraphicsPaletteSelection > preview_palettes
std::optional< GraphicsEditContext > source_context
static Arena & Get()
Definition arena.cc:24
static PaletteManager & Get()
Get the singleton instance.
SNES Color container.
Definition snes_color.h:110
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
int GetPaletteRowCount(std::size_t palette_size, int colors_per_row)
PaletteRowLayout GetPaletteRowLayout(std::string_view group_name, std::size_t palette_size)
Editors are the view controllers for the application.
absl::Status SetGraphicsPreviewPalette(GraphicsEditorState &state, uint16_t sheet, std::optional< GraphicsPaletteSelection > selection)
absl::StatusOr< GraphicsPalettePreview > ResolveGraphicsPreviewPalette(zelda3::GameData &data, const GraphicsPaletteSelection &selection)
void RefreshGraphicsPreviewPalettes(GraphicsEditorState &state)
SDL_Palette * GetSurfacePalette(SDL_Surface *surface)
Get the palette attached to a surface.
Definition sdl_compat.h:398
SDL2/SDL3 compatibility layer.
PaletteGroup * get_group(const std::string &group_name)
gfx::PaletteGroupMap palette_groups
Definition game_data.h:95
std::array< gfx::Bitmap, kNumGfxSheets > gfx_bitmaps
Definition game_data.h:90