yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_editor_v2_graphics_preview.cc
Go to the documentation of this file.
2
3#include <array>
4#include <cstdint>
5#include <memory>
6#include <optional>
7#include <utility>
8#include <vector>
9
10#include "absl/status/status.h"
11#include "absl/status/statusor.h"
16#include "util/macro.h"
17#include "zelda3/dungeon/room.h"
19
20namespace yaze::editor {
21
23 GraphicsEditContext& context, int room_id,
24 std::function<absl::Status(GraphicsEditContext&)> resolve_live_source) {
25 struct StagedSourceStamp {
26 std::optional<DungeonRoomDocument> document;
28 std::array<uint8_t, 16> blocks{};
29 uint8_t main_blockset = 0xff;
30 uint64_t palette_revision = 0;
31 uint64_t revision = 0;
32 };
33 auto staged_stamp = std::make_shared<StagedSourceStamp>();
34 context.preview_revision = [this, room_id, owner = game_data_,
35 source_rom = rom_,
36 staged_stamp]() -> absl::StatusOr<uint64_t> {
37 if (game_data_ != owner || rom_ != source_rom || !rom_ ||
38 !rom_->is_loaded()) {
39 return absl::FailedPreconditionError("Dungeon source session changed");
40 }
41 const auto* source = rooms_.GetIfMaterialized(room_id);
42 if (!source || !source->IsLoaded())
43 return absl::FailedPreconditionError("Dungeon source room changed");
44 // Cache invalidation also advances composite_source_revision. Compare
45 // authored inputs instead, so ordinary source-preview refreshes do not
46 // discard a candidate. Full pixels also catch an uncommitted stroke.
47 auto document = CaptureDungeonRoomDocument(*source);
49 for (const auto sheet : source->blocks()) {
50 if (!owner->sheet_store.HasSheet(sheet))
51 continue;
52 const auto pixels = owner->sheet_store.Sheet(sheet);
53 sheets.emplace(sheet, std::vector<uint8_t>(pixels.begin(), pixels.end()));
54 }
55 const auto palette_revision =
57 if (!staged_stamp->document ||
58 !SameDungeonRoomDocument(*staged_stamp->document, document) ||
59 staged_stamp->sheets != sheets ||
60 staged_stamp->blocks != source->blocks() ||
61 staged_stamp->main_blockset != source->resolved_main_blockset() ||
62 staged_stamp->palette_revision != palette_revision) {
63 staged_stamp->document = std::move(document);
64 staged_stamp->sheets = std::move(sheets);
65 staged_stamp->blocks = source->blocks();
66 staged_stamp->main_blockset = source->resolved_main_blockset();
67 staged_stamp->palette_revision = palette_revision;
68 ++staged_stamp->revision;
69 }
70 return staged_stamp->revision;
71 };
72 context.render_staged_preview =
73 [this, room_id, owner = game_data_, source_rom = rom_,
74 resolve_live_source = std::move(resolve_live_source)](
75 const usage_preview::SheetPixels& sheets)
76 -> absl::StatusOr<usage_preview::PreviewImage> {
78 RETURN_IF_ERROR(resolve_live_source(fresh));
79 if (game_data_ != owner || rom_ != source_rom)
80 return absl::FailedPreconditionError("Dungeon source session changed");
81 auto* source = rooms_.GetIfMaterialized(room_id);
82 if (!source || !source->IsLoaded())
83 return absl::FailedPreconditionError("Dungeon source room changed");
84 // Reuse the authored-room document and normal room renderer on a detached
85 // room. Neither the active Room nor the session sheet store receives the
86 // candidate pixels merely to try an asset.
87 auto detached = zelda3::LoadRoomFromRom(source_rom, room_id);
88 detached.SetGameData(owner);
89 detached.EnsureObjectsLoaded();
91 detached.SetRenderEntranceBlockset(source->render_entrance_blockset());
92 detached.SetGraphicsSheetOverrides(sheets);
93 detached.PrepareForRender();
95 layers.ApplyLayerMerging(detached.layer_merging());
96 layers.ApplyRoomEffect(detached.effect());
97 layers.ApplyGameLayerRegisters(detached.GameLayerRegisters());
98 gfx::Bitmap composite;
99 detached.RenderComposite(layers, composite);
100 return usage_preview::SnapshotBitmap(composite);
101 };
102}
103
104} // namespace yaze::editor
bool is_loaded() const
Definition rom.h:199
void ConfigureStagedGraphicsPreview(GraphicsEditContext &context, int room_id, std::function< absl::Status(GraphicsEditContext &)> resolve_live_source)
zelda3::Room * GetIfMaterialized(int room_id)
EditorContext context() const
Definition editor.h:376
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:70
uint64_t ColorRevision(const zelda3::GameData *game_data) const
static PaletteManager & Get()
Get the singleton instance.
RoomLayerManager - Manages layer visibility and compositing.
void ApplyGameLayerRegisters(const RoomLayerRegisters &registers)
void ApplyLayerMerging(const LayerMergeType &merge_type)
void ApplyRoomEffect(EffectKey effect)
std::map< uint16_t, std::vector< uint8_t > > SheetPixels
Sheet id -> 4096 8bpp pixels (the GameData::graphics_buffer layout).
PreviewImage SnapshotBitmap(const gfx::Bitmap &bitmap)
Copies a palettized Bitmap (for example a room composite).
Editors are the view controllers for the application.
bool SameDungeonRoomDocument(const DungeonRoomDocument &a, const DungeonRoomDocument &b)
void ApplyDungeonRoomDocument(zelda3::Room &room, const DungeonRoomDocument &document)
DungeonRoomDocument CaptureDungeonRoomDocument(const zelda3::Room &room)
Room LoadRoomFromRom(Rom *rom, int room_id)
Definition room.cc:655
#define RETURN_IF_ERROR(expr)
Definition snes.cc:22
Renders a graphics sheet the way the game uses it, from unsaved sheet pixels, without writing the ROM...