15 "track_corner_TL.bin",
16 "track_corner_TR.bin",
17 "track_corner_BL.bin",
18 "track_corner_BR.bin",
21 "track_floor_corner_TL.bin",
22 "track_floor_corner_TR.bin",
23 "track_floor_corner_BL.bin",
24 "track_floor_corner_BR.bin",
25 "track_floor_any.bin",
26 "wall_sword_house.bin",
46 LOG_INFO(
"CustomObjectManager",
"Initialize: base_path='%s'",
51 "Object 0x31 file list has %zu entries (corners need indices 2-5)",
55 "Object 0x31 not mapped - corner overrides 0x100-0x103 will fail");
61 const std::unordered_map<
int, std::vector<std::string>>& map) {
72 int object_id)
const {
75 return &custom_it->second;
77 if (object_id == 0x31) {
80 if (object_id == 0x32) {
87 const std::string& filename) {
88 if (
cache_.contains(filename)) {
93 std::filesystem::path full_path =
96 std::ifstream file(full_path, std::ios::binary);
98 LOG_ERROR(
"CustomObjectManager",
"Failed to open file: %s",
100 return absl::NotFoundError(
"Could not open file: " + full_path.string());
104 std::vector<uint8_t> buffer((std::istreambuf_iterator<char>(file)),
105 std::istreambuf_iterator<char>());
108 if (!object_or_error.ok()) {
109 return object_or_error.status();
113 std::make_shared<CustomObject>(std::move(object_or_error.value()));
114 cache_[filename] = object_ptr;
120 const std::vector<uint8_t>& data) {
123 int current_buffer_pos = 0;
133 constexpr int kBufferStride = 128;
135 while (cursor + 1 < data.size()) {
137 uint16_t header = data[cursor] | (data[cursor + 1] << 8);
143 int count = header & 0x001F;
144 int jump_offset = (header >> 8) & 0xFF;
149 int row_start_pos = current_buffer_pos;
152 for (
int i = 0; i < count; ++i) {
153 if (cursor + 1 >= data.size()) {
155 "Unexpected end of file parsing object");
159 uint16_t tile_data = data[cursor] | (data[cursor + 1] << 8);
164 int rel_y = current_buffer_pos / kBufferStride;
165 int rel_x = (current_buffer_pos % kBufferStride) / 2;
167 obj.
tiles.push_back({rel_x, rel_y, tile_data});
169 current_buffer_pos += 2;
174 current_buffer_pos = row_start_pos + jump_offset;
180absl::StatusOr<std::shared_ptr<CustomObject>>
185 if (!list && object_id >= 0x100 && object_id <= 0x103) {
209 return absl::NotFoundError(
"Object ID not mapped to custom object");
212 if (index < 0 || index >=
static_cast<int>(list->size())) {
213 return absl::OutOfRangeError(
"Subtype index out of range");
221 return static_cast<int>(list->size());
223 if (object_id >= 0x100 && object_id <= 0x103) {
225 return static_cast<int>(list->size());
232 const std::string& filename) {
249 int object_id)
const {
263 if (!list && object_id >= 0x100 && object_id <= 0x103) {
266 if (list && subtype >= 0 && subtype <
static_cast<int>(list->size())) {
267 return (*list)[subtype];
Manages loading and caching of custom object binary files.
int GetSubtypeCount(int object_id) const
void RestoreState(const State &state)
absl::StatusOr< CustomObject > ParseBinaryData(const std::vector< uint8_t > &data)
void SetObjectFileMap(const std::unordered_map< int, std::vector< std::string > > &map)
static CustomObjectManager & Get()
absl::StatusOr< std::shared_ptr< CustomObject > > LoadObject(const std::string &filename)
void AddObjectFile(int object_id, const std::string &filename)
absl::StatusOr< std::shared_ptr< CustomObject > > GetObjectInternal(int object_id, int subtype)
static const std::vector< std::string > kSubtype2Filenames
void Initialize(const std::string &custom_objects_folder)
std::unordered_map< std::string, std::shared_ptr< CustomObject > > cache_
const std::vector< std::string > * ResolveFileList(int object_id) const
void ClearObjectFileMap()
std::unordered_map< int, std::vector< std::string > > custom_file_map_
std::string ResolveFilename(int object_id, int subtype) const
static const std::vector< std::string > kSubtype1Filenames
std::vector< std::string > GetEffectiveFileList(int object_id) const
State SnapshotState() const
#define LOG_ERROR(category, format,...)
#define LOG_WARN(category, format,...)
#define LOG_INFO(category, format,...)
std::unordered_map< int, std::vector< std::string > > custom_file_map
Represents a decoded custom object (from binary format)
std::vector< TileMapEntry > tiles