9#include "absl/strings/str_format.h"
22 int frame_index,
int oam_index,
23 const std::array<uint8_t, 8>& slots,
26 const std::string& source_label,
27 const std::string& sheet_source) {
28 if (!owner || oam_index < 0 ||
29 oam_index >=
static_cast<int>(frame.
Tiles.size())) {
30 return absl::InvalidArgumentError(
"Select a sprite frame and OAM tile");
32 const auto& oam = frame.
Tiles[oam_index];
33 if (oam.palette >= palettes.
size() ||
35 return absl::FailedPreconditionError(
"Selected OAM palette is unresolved");
37 const auto& row = palettes.
palette_ref(oam.palette);
38 std::vector<gfx::SnesColor> colors;
39 for (
int i = 0; i < 8; ++i)
40 colors.push_back(row[i]);
42 context.
owner = owner;
44 absl::StrFormat(
"%s / frame %d / OAM %d / palette %d", source_label,
45 frame_index, oam_index, oam.palette);
47 "Captured pose and sheet assignments; re-enter from Sprite Editor after "
55 {absl::StrFormat(
"OAM palette row %d", oam.palette), sheet_source,
57 for (
int slot = 0; slot < 8; ++slot) {
58 const uint16_t sheet = slots[slot];
62 .role = slot < 4 ?
"static_sprite" :
"spriteset_sprite",
63 .palette_group = absl::StrFormat(
"sprite_row_%d", oam.palette),
65 .source = sheet_source,
66 .loader_agrees = loaded,
73 const int offsets[] = {0, 1, 16, 17};
74 const int count = oam.size ? 4 : 1;
75 for (
int i = 0; i < count; ++i) {
76 const int tile =
static_cast<int>(oam.id) + offsets[i];
77 if (tile < 0 || tile >= 512) {
78 return absl::OutOfRangeError(
"Selected OAM tile extends past tile 0x1FF");
81 const uint16_t sheet = slots[slot];
85 return absl::FailedPreconditionError(absl::StrFormat(
86 "OAM tile %03X uses unavailable or 2bpp sheet %02X", tile, sheet));
90 .tile_index =
static_cast<uint16_t
>(tile % 64),
91 .label = absl::StrFormat(
92 "Frame %d / OAM %d / tile %03X / slot %d / sheet %02X / palette %d",
93 frame_index, oam_index, tile, slot, sheet, oam.palette),
106 return absl::FailedPreconditionError(
"Sprite ROM session ended");
107 std::set<uint16_t> ids(slots.begin(), slots.end());
109 std::vector<uint8_t> buffer(0x10000, 0);
110 for (
size_t slot = 0; slot < slots.size(); ++slot) {
111 const auto it = sheets.find(slots[slot]);
112 if (it == sheets.end() || it->second.size() != 4096) {
113 return absl::FailedPreconditionError(
114 "Sprite sheet unavailable in source session");
116 std::copy(it->second.begin(), it->second.end(),
117 buffer.begin() + slot * 4096);
119 constexpr int kSize = 256;
120 gfx::Bitmap canvas(kSize, kSize, 8, std::vector<uint8_t>(kSize * kSize, 0));
122 drawer.
DrawFrame(canvas, frame, 128, 128);
128 for (
size_t row = 0; row < palettes.
size() && row < 8; ++row) {
130 for (
size_t index = 0; index < palette.size() && index < 16; ++index) {
131 const auto rgb = palette[index].rgb();
132 image.
colors[row * 16 + index] = {
static_cast<uint8_t
>(rgb.x),
133 static_cast<uint8_t
>(rgb.y),
134 static_cast<uint8_t
>(rgb.z), 255};
Draws sprite OAM tiles to bitmaps for preview rendering.
void DrawFrame(gfx::Bitmap &bitmap, const zsprite::Frame &frame, int origin_x, int origin_y)
Draw all tiles in a ZSM frame.
Represents a bitmap image optimized for SNES ROM hacking.
const std::vector< uint8_t > & vector() const
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
bool HasSheet(uint16_t sheet) const
True when the buffer holds all 4096 bytes of sheet.
uint64_t Revision(uint16_t sheet) const
Locates graphics sheets in the ROM and writes edited sheets back.
absl::StatusOr< GraphicsEditContext > Make(const zsprite::Frame &frame, int frame_index, int oam_index, const std::array< uint8_t, 8 > &slots, const gfx::PaletteGroup &palettes, const zelda3::GameData *owner, const std::string &source_label, const std::string &sheet_source)
absl::StatusOr< usage_preview::PreviewImage > RenderCapturedFrame(const zsprite::Frame &frame, const std::array< uint8_t, 8 > &slots, const gfx::PaletteGroup &palettes, const zelda3::GameData *owner)
SheetPixels SnapshotSessionSheets(const std::set< uint16_t > &ids, const zelda3::GameData *game_data)
GfxSheetStorageKind GetGfxSheetStorageKind(uint16_t sheet_id)
constexpr int SpriteSlotForTile(int tile)
Slot (0-7) holding 8x8 OAM tile tile (name-table bit included).
Which graphics sheets back sprite OAM tiles 0x000-0x1FF.
zelda3::ResolvedGraphicsContext resolved
std::vector< GraphicsEditTarget > targets
const zelda3::GameData * owner
std::array< SDL_Color, 256 > colors
std::vector< uint8_t > pixels
std::vector< OamTile > Tiles
Represents a group of palettes.
const SnesPalette & palette_ref(int i) const
GraphicsSheetStore sheet_store
std::vector< ResolvedPaletteSource > palettes
bool palette_colors_resolved
std::vector< ResolvedGraphicsSlot > slots
Renders a graphics sheet the way the game uses it, from unsaved sheet pixels, without writing the ROM...