3#include "absl/status/status.h"
20 if (object_id >= 0x200) {
22 }
else if (object_id >= 0x100) {
32 static_cast<int>(rhs));
37 static_cast<int>(rhs));
42 static_cast<int>(rhs));
46 return static_cast<ObjectOption>(~static_cast<int>(option));
57 if (
rom_ ==
nullptr) {
63 if (parser_status.ok()) {
72 SubtypeTableInfo sti = GetSubtypeTable(
id_);
73 int index = (
id_ & sti.index_mask);
74 int tile_ptr = sti.base_ptr + (index * 2);
77 if (tile_ptr < 0 || tile_ptr + 1 >= (
int)
rom_->
size()) {
82 int tile_rel = (int16_t)((rom_data[tile_ptr + 1] << 8) + rom_data[tile_ptr]);
87 if (pos < 0 || pos + 7 >= (
int)
rom_->
size()) {
93 uint16_t w0 = (uint16_t)(rom_data[pos] | (rom_data[pos + 1] << 8));
94 uint16_t w1 = (uint16_t)(rom_data[pos + 2] | (rom_data[pos + 3] << 8));
95 uint16_t w2 = (uint16_t)(rom_data[pos + 4] | (rom_data[pos + 5] << 8));
96 uint16_t w3 = (uint16_t)(rom_data[pos + 6] | (rom_data[pos + 7] << 8));
108 if (
rom_ ==
nullptr) {
109 return absl::InvalidArgumentError(
"ROM is null");
115 return result.status();
118 tiles_ = std::move(result.value());
120 return absl::OkStatus();
129 return absl::FailedPreconditionError(
"No tiles loaded for object");
132 return std::span<const gfx::TileInfo>(
tiles_.data(),
tiles_.size());
140 if (index < 0 || index >=
static_cast<int>(
tiles_.size())) {
141 return absl::OutOfRangeError(
142 absl::StrFormat(
"Tile index %d out of range (0-%d)", index,
tiles_.size() - 1));
185 id = (
static_cast<uint16_t
>(b3) << 4) | 0x80 |
186 ((
static_cast<uint16_t
>(b2 & 0x03) << 2) + (b1 & 0x03));
187 x = (b1 & 0xFC) >> 2;
188 y = (b2 & 0xFC) >> 2;
189 size = ((b1 & 0x03) << 2) | (b2 & 0x03);
190 LOG_DEBUG(
"ObjectParser",
"Type3: b1=%02X b2=%02X b3=%02X -> id=%04X x=%d y=%d size=%d",
191 b1, b2, b3,
id,
x,
y,
size);
195 x = (b1 & 0xFC) >> 2;
196 y = (b2 & 0xFC) >> 2;
197 size = ((b1 & 0x03) << 2) | (b2 & 0x03);
201 id = (b3 & 0x3F) | 0x100;
202 x = ((b2 & 0xF0) >> 4) | ((b1 & 0x03) << 4);
203 y = ((b2 & 0x0F) << 2) | ((b3 & 0xC0) >> 6);
205 LOG_DEBUG(
"ObjectParser",
"Type2: b1=%02X b2=%02X b3=%02X -> id=%04X x=%d y=%d size=%d",
206 b1, b2, b3,
id,
x,
y,
size);
208 LOG_DEBUG(
"ObjectParser",
"Type1: b1=%02X b2=%02X b3=%02X -> id=%04X x=%d y=%d size=%d",
209 b1, b2, b3,
id,
x,
y,
size);
220 if (
id_ >= 0x100 &&
id_ < 0x200) {
222 bytes.
b1 = 0xFC | ((
x_ & 0x30) >> 4);
223 bytes.
b2 = ((
x_ & 0x0F) << 4) | ((
y_ & 0x3C) >> 2);
224 bytes.
b3 = ((
y_ & 0x03) << 6) | (
id_ & 0x3F);
225 }
else if (
id_ >= 0xF00) {
227 bytes.
b1 = (
x_ << 2) | (
id_ & 0x03);
228 bytes.
b2 = (
y_ << 2) | ((
id_ >> 2) & 0x03);
229 bytes.
b3 = (
id_ >> 4) & 0xFF;
232 uint8_t clamped_size =
size_ > 15 ? 15 :
size_;
233 bytes.
b1 = (
x_ << 2) | ((clamped_size >> 2) & 0x03);
234 bytes.
b2 = (
y_ << 2) | (clamped_size & 0x03);
235 bytes.
b3 =
static_cast<uint8_t
>(
id_);
Direct ROM parser for dungeon objects.
absl::StatusOr< std::vector< gfx::TileInfo > > ParseObject(int16_t object_id)
Parse object data directly from ROM.
absl::StatusOr< const gfx::TileInfo * > GetTile(int index) const
static RoomObject DecodeObjectFromBytes(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t layer)
std::vector< gfx::TileInfo > tiles_
ObjectBytes EncodeObjectToBytes() const
static int DetermineObjectType(uint8_t b1, uint8_t b3)
absl::Status LoadTilesWithParser()
absl::StatusOr< std::span< const gfx::TileInfo > > GetTiles() const
#define LOG_DEBUG(category, format,...)
TileInfo WordToTileInfo(uint16_t word)
SubtypeTableInfo GetSubtypeTable(int object_id)
constexpr int kRoomObjectSubtype3
ObjectOption operator|(ObjectOption lhs, ObjectOption rhs)
ObjectOption operator^(ObjectOption lhs, ObjectOption rhs)
constexpr int kRoomObjectSubtype1
constexpr int kRoomObjectSubtype2
constexpr int kRoomObjectTileAddress
ObjectOption operator~(ObjectOption option)
ObjectOption operator&(ObjectOption lhs, ObjectOption rhs)
Main namespace for the application.
SubtypeTableInfo(int base, int mask)