yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
tile16_stamp.cc
Go to the documentation of this file.
2
3#include <algorithm>
4
5#include "absl/status/status.h"
7
8namespace yaze::zelda3 {
9namespace {
10
11uint16_t ClampTile8Id(int tile8_id, int max_tile8_id) {
12 return static_cast<uint16_t>(std::clamp(tile8_id, 0, max_tile8_id));
13}
14
16 int tile8_id) {
17 return gfx::TileInfo(ClampTile8Id(tile8_id, request.max_tile8_id),
18 request.palette_id, request.y_flip, request.x_flip,
19 request.priority);
20}
21
22gfx::Tile16 Make2xStampTile(const Tile16StampRequest& request, int base_tile8,
23 bool reorder_for_flip_layout) {
24 const gfx::TileInfo t0 = MakeStampedTileInfo(request, base_tile8);
25 const gfx::TileInfo t1 = MakeStampedTileInfo(request, base_tile8 + 1);
26 const gfx::TileInfo t2 =
27 MakeStampedTileInfo(request, base_tile8 + request.tile8_row_stride);
28 const gfx::TileInfo t3 =
29 MakeStampedTileInfo(request, base_tile8 + request.tile8_row_stride + 1);
30
31 gfx::Tile16 stamped_tile{};
32 if (reorder_for_flip_layout && request.x_flip && request.y_flip) {
33 stamped_tile = gfx::Tile16(t3, t2, t1, t0);
34 } else if (reorder_for_flip_layout && request.x_flip) {
35 stamped_tile = gfx::Tile16(t1, t0, t3, t2);
36 } else if (reorder_for_flip_layout && request.y_flip) {
37 stamped_tile = gfx::Tile16(t2, t3, t0, t1);
38 } else {
39 stamped_tile = gfx::Tile16(t0, t1, t2, t3);
40 }
41 SyncTile16TilesInfo(&stamped_tile);
42 return stamped_tile;
43}
44
45} // namespace
46
47absl::StatusOr<std::vector<Tile16StampMutation>> BuildTile16StampMutations(
48 const Tile16StampRequest& request) {
49 if (request.tile8_row_stride <= 0) {
50 return absl::InvalidArgumentError("tile8_row_stride must be positive");
51 }
52 if (request.tile16_row_stride <= 0) {
53 return absl::InvalidArgumentError("tile16_row_stride must be positive");
54 }
55 if (request.max_tile8_id < 0) {
56 return absl::InvalidArgumentError("max_tile8_id must be non-negative");
57 }
58 if (request.max_tile16_id < 0) {
59 return absl::InvalidArgumentError("max_tile16_id must be non-negative");
60 }
61 if (request.current_tile16_id < 0 ||
62 request.current_tile16_id > request.max_tile16_id) {
63 return absl::OutOfRangeError("current_tile16_id out of range");
64 }
65
66 std::vector<Tile16StampMutation> mutations;
67 const bool is_1x_stamp = request.stamp_size == 1;
68 const bool is_2x_stamp = request.stamp_size == 2;
69
70 if (is_1x_stamp) {
71 gfx::Tile16 staged_current = request.current_tile16;
72 MutableTile16QuadrantInfo(staged_current, request.quadrant_index) =
73 MakeStampedTileInfo(request, request.selected_tile8_id);
74 SyncTile16TilesInfo(&staged_current);
75 mutations.push_back(
76 Tile16StampMutation{request.current_tile16_id, staged_current});
77 return mutations;
78 }
79
80 if (is_2x_stamp) {
81 mutations.push_back(Tile16StampMutation{
82 request.current_tile16_id,
83 Make2xStampTile(request, request.selected_tile8_id, true)});
84 return mutations;
85 }
86
87 // ZScream parity: 4x paints a 2x2 tile16 patch from a 4x4 tile8 region.
88 for (int patch_x = 0; patch_x < 2; ++patch_x) {
89 for (int patch_y = 0; patch_y < 2; ++patch_y) {
90 const int target_tile16 = request.current_tile16_id +
91 (patch_x + patch_y * request.tile16_row_stride);
92 if (target_tile16 < 0 || target_tile16 > request.max_tile16_id) {
93 continue;
94 }
95
96 const int base_tile8 = request.selected_tile8_id + (patch_x * 2) +
97 (patch_y * request.tile8_row_stride * 2);
98 mutations.push_back(Tile16StampMutation{
99 target_tile16, Make2xStampTile(request, base_tile8, false)});
100 }
101 }
102
103 return mutations;
104}
105
106} // namespace yaze::zelda3
Tile composition of four 8x8 tiles.
Definition snes_tile.h:142
SNES 16-bit tile metadata container.
Definition snes_tile.h:52
gfx::TileInfo MakeStampedTileInfo(const Tile16StampRequest &request, int tile8_id)
gfx::Tile16 Make2xStampTile(const Tile16StampRequest &request, int base_tile8, bool reorder_for_flip_layout)
uint16_t ClampTile8Id(int tile8_id, int max_tile8_id)
Zelda 3 specific classes and functions.
gfx::TileInfo & MutableTile16QuadrantInfo(gfx::Tile16 &tile, int quadrant)
void SyncTile16TilesInfo(gfx::Tile16 *tile)
absl::StatusOr< std::vector< Tile16StampMutation > > BuildTile16StampMutations(const Tile16StampRequest &request)