yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
tile16_usage_index.cc
Go to the documentation of this file.
2
3#include <algorithm>
4
5namespace yaze::zelda3 {
6
7namespace {
8
9const gfx::TileInfo& TileInfoForQuadrant(const gfx::Tile16& tile,
10 int quadrant) {
11 switch (quadrant) {
12 case 0:
13 return tile.tile0_;
14 case 1:
15 return tile.tile1_;
16 case 2:
17 return tile.tile2_;
18 default:
19 return tile.tile3_;
20 }
21}
22
23} // namespace
24
26 if (!usage_index) {
27 return;
28 }
29 for (auto& hits : *usage_index) {
30 hits.clear();
31 }
32}
33
34void AddTile16ToUsageIndex(const gfx::Tile16& tile_data, int tile16_id,
35 Tile8UsageIndex* usage_index) {
36 if (!usage_index) {
37 return;
38 }
39
40 for (int quadrant = 0; quadrant < 4; ++quadrant) {
41 const int tile8_id = TileInfoForQuadrant(tile_data, quadrant).id_;
42 if (tile8_id < 0 || tile8_id >= kMaxTile8UsageId) {
43 continue;
44 }
45 (*usage_index)[tile8_id].push_back({tile16_id, quadrant});
46 }
47}
48
50 int total_tiles,
51 const std::function<absl::StatusOr<gfx::Tile16>(int)>& tile_provider,
52 Tile8UsageIndex* usage_index) {
53 if (!usage_index) {
54 return absl::InvalidArgumentError("Usage index pointer is null");
55 }
56 if (!tile_provider) {
57 return absl::InvalidArgumentError("Tile provider callback is not set");
58 }
59 if (total_tiles < 0) {
60 return absl::InvalidArgumentError("Total tiles cannot be negative");
61 }
62
63 ClearTile8UsageIndex(usage_index);
64 for (int tile_id = 0; tile_id < total_tiles; ++tile_id) {
65 auto tile_result = tile_provider(tile_id);
66 if (!tile_result.ok()) {
67 continue;
68 }
69 AddTile16ToUsageIndex(*tile_result, tile_id, usage_index);
70 }
71 return absl::OkStatus();
72}
73
75 const std::vector<std::vector<uint16_t>>& world_tiles, int local_map,
76 std::vector<int>* counts) {
77 constexpr int kMapsPerRow = 8;
78 constexpr int kTilesPerMapSide = 32;
79 if (!counts || local_map < 0) {
80 return;
81 }
82 const int x0 = (local_map % kMapsPerRow) * kTilesPerMapSide;
83 const int y0 = (local_map / kMapsPerRow) * kTilesPerMapSide;
84 const int x_end =
85 std::min(x0 + kTilesPerMapSide, static_cast<int>(world_tiles.size()));
86 for (int x = x0; x < x_end; ++x) {
87 const auto& column = world_tiles[x];
88 const int y_end =
89 std::min(y0 + kTilesPerMapSide, static_cast<int>(column.size()));
90 for (int y = y0; y < y_end; ++y) {
91 const uint16_t tile_id = column[y];
92 if (tile_id < counts->size()) {
93 ++(*counts)[tile_id];
94 }
95 }
96 }
97}
98
99std::vector<int> BuildTile16DisplayOrder(const std::vector<int>& counts,
100 Tile16SortMode sort_mode,
101 bool hide_unused) {
102 std::vector<int> order;
103 order.reserve(counts.size());
104 for (int tile_id = 0; tile_id < static_cast<int>(counts.size()); ++tile_id) {
105 if (!hide_unused || counts[tile_id] > 0) {
106 order.push_back(tile_id);
107 }
108 }
109 if (sort_mode == Tile16SortMode::kUsage) {
110 std::stable_sort(order.begin(), order.end(),
111 [&counts](int a, int b) { return counts[a] > counts[b]; });
112 }
113 return order;
114}
115
116} // 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
Zelda 3 specific classes and functions.
void AccumulateTile16MapUsage(const std::vector< std::vector< uint16_t > > &world_tiles, int local_map, std::vector< int > *counts)
void ClearTile8UsageIndex(Tile8UsageIndex *usage_index)
absl::Status BuildTile8UsageIndex(int total_tiles, const std::function< absl::StatusOr< gfx::Tile16 >(int)> &tile_provider, Tile8UsageIndex *usage_index)
std::vector< int > BuildTile16DisplayOrder(const std::vector< int > &counts, Tile16SortMode sort_mode, bool hide_unused)
std::array< std::vector< Tile8UsageHit >, kMaxTile8UsageId > Tile8UsageIndex
constexpr int kMaxTile8UsageId
void AddTile16ToUsageIndex(const gfx::Tile16 &tile_data, int tile16_id, Tile8UsageIndex *usage_index)