OverworldEntity update: Entrances, Exits, Items
This commit is contained in:
@@ -141,10 +141,9 @@ absl::Status Overworld::Load(ROM &rom) {
|
||||
FetchLargeMaps();
|
||||
LoadEntrances();
|
||||
LoadExits();
|
||||
LoadSprites();
|
||||
RETURN_IF_ERROR(LoadItems());
|
||||
RETURN_IF_ERROR(LoadOverworldMaps())
|
||||
if (flags()->overworld.kDrawOverworldSprites) {
|
||||
LoadSprites();
|
||||
}
|
||||
|
||||
is_loaded_ = true;
|
||||
return absl::OkStatus();
|
||||
@@ -213,10 +212,10 @@ absl::Status Overworld::SaveOverworldMaps() {
|
||||
}
|
||||
|
||||
// Compress single_map_1 and single_map_2
|
||||
ASSIGN_OR_RETURN(
|
||||
auto a, gfx::lc_lz2::CompressOverworld(single_map_1, 0, 256))
|
||||
ASSIGN_OR_RETURN(
|
||||
auto b, gfx::lc_lz2::CompressOverworld(single_map_2, 0, 256))
|
||||
ASSIGN_OR_RETURN(auto a,
|
||||
gfx::lc_lz2::CompressOverworld(single_map_1, 0, 256))
|
||||
ASSIGN_OR_RETURN(auto b,
|
||||
gfx::lc_lz2::CompressOverworld(single_map_2, 0, 256))
|
||||
if (a.empty() || b.empty()) {
|
||||
return absl::AbortedError("Error compressing map gfx.");
|
||||
}
|
||||
@@ -557,13 +556,17 @@ absl::Status Overworld::SaveMap16Tiles() {
|
||||
int tpos = kMap16Tiles;
|
||||
// 3760
|
||||
for (int i = 0; i < NumberOfMap16; i += 1) {
|
||||
RETURN_IF_ERROR(rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile0_)))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile0_)))
|
||||
tpos += 2;
|
||||
RETURN_IF_ERROR(rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile1_)))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile1_)))
|
||||
tpos += 2;
|
||||
RETURN_IF_ERROR(rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile2_)))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile2_)))
|
||||
tpos += 2;
|
||||
RETURN_IF_ERROR(rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile3_)))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(tpos, TileInfoToShort(tiles16_[i].tile3_)))
|
||||
tpos += 2;
|
||||
}
|
||||
return absl::OkStatus();
|
||||
@@ -936,6 +939,85 @@ absl::Status Overworld::SaveExits() {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status Overworld::SaveItems() {
|
||||
std::vector<std::vector<OverworldItem>> roomItems(128);
|
||||
|
||||
for (int i = 0; i < 128; i++) {
|
||||
roomItems[i] = std::vector<OverworldItem>();
|
||||
for (const OverworldItem &item : all_items_) {
|
||||
if (item.room_map_id == i) {
|
||||
roomItems[i].push_back(item);
|
||||
if (item.id == 0x86) {
|
||||
rom()->WriteWord(0x16DC5 + (i * 2),
|
||||
(item.game_x_ + (item.game_y_ * 64)) * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int dataPos = overworldItemsPointers + 0x100;
|
||||
|
||||
std::vector<int> itemPointers(128);
|
||||
std::vector<int> itemPointersReuse(128);
|
||||
int emptyPointer = 0;
|
||||
|
||||
for (int i = 0; i < 128; i++) {
|
||||
itemPointersReuse[i] = -1;
|
||||
for (int ci = 0; ci < i; ci++) {
|
||||
if (roomItems[i].empty()) {
|
||||
itemPointersReuse[i] = -2;
|
||||
break;
|
||||
}
|
||||
// Unclear: this.compareItemsArrays(roomItems[i].ToArray(),
|
||||
// roomItems[ci].ToArray()) Commenting out for now if
|
||||
// (this.compareItemsArrays(roomItems[i].ToArray(),
|
||||
// roomItems[ci].ToArray())) {
|
||||
// itemPointersReuse[i] = ci;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 128; i++) {
|
||||
if (itemPointersReuse[i] == -1) {
|
||||
itemPointers[i] = dataPos;
|
||||
for (const OverworldItem &item : roomItems[i]) {
|
||||
short mapPos =
|
||||
static_cast<short>(((item.game_y_ << 6) + item.game_x_) << 1);
|
||||
|
||||
uint32_t data = static_cast<uint8_t>(mapPos & 0xFF) |
|
||||
static_cast<uint8_t>(mapPos >> 8) |
|
||||
static_cast<uint8_t>(item.id);
|
||||
rom()->WriteLong(dataPos, data);
|
||||
// WriteType::PotItemData);
|
||||
|
||||
dataPos += 3;
|
||||
}
|
||||
|
||||
emptyPointer = dataPos;
|
||||
rom()->WriteWord(dataPos, 0xFFFF);
|
||||
dataPos += 2;
|
||||
} else if (itemPointersReuse[i] == -2) {
|
||||
itemPointers[i] = emptyPointer;
|
||||
} else {
|
||||
itemPointers[i] = itemPointers[itemPointersReuse[i]];
|
||||
}
|
||||
|
||||
int snesaddr = core::PcToSnes(itemPointers[i]);
|
||||
rom()->WriteWord(overworldItemsPointers + (i * 2), snesaddr);
|
||||
}
|
||||
|
||||
if (dataPos > overworldItemsEndData) {
|
||||
return absl::AbortedError("Too many items");
|
||||
}
|
||||
|
||||
if (flags()->kLogToConsole) {
|
||||
std::cout << "End of Items : " << dataPos << std::endl;
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void Overworld::LoadExits() {
|
||||
const int NumberOfOverworldExits = 0x4F;
|
||||
std::vector<OverworldExit> exits;
|
||||
@@ -987,7 +1069,7 @@ void Overworld::LoadExits() {
|
||||
<< " DoorType2: " << exit_door_type_2 << std::endl;
|
||||
}
|
||||
|
||||
if (px == 0xFFFF && py == 0xFFFF) {
|
||||
if ((px & py) == 0xFFFF) {
|
||||
exit.deleted = true;
|
||||
}
|
||||
|
||||
@@ -996,6 +1078,55 @@ void Overworld::LoadExits() {
|
||||
all_exits_ = exits;
|
||||
}
|
||||
|
||||
absl::Status Overworld::LoadItems() {
|
||||
ASSIGN_OR_RETURN(int pointer, rom()->ReadLong(zelda3::overworldItemsAddress));
|
||||
int oointerPC = core::SnesToPc(pointer); // 1BC2F9 -> 0DC2F9
|
||||
for (int i = 0; i < 128; i++) {
|
||||
int addr = (pointer & 0xFF0000) + // 1B
|
||||
(rom()->data()[oointerPC + (i * 2) + 1] << 8) + // F9
|
||||
rom()->data()[oointerPC + (i * 2)]; // 3C
|
||||
|
||||
addr = core::SnesToPc(addr);
|
||||
|
||||
if (overworld_maps_[i].IsLargeMap()) {
|
||||
if (overworld_maps_[i].Parent() != (uint8_t)i) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
uint8_t b1 = rom()->data()[addr];
|
||||
uint8_t b2 = rom()->data()[addr + 1];
|
||||
uint8_t b3 = rom()->data()[addr + 2];
|
||||
|
||||
if (b1 == 0xFF && b2 == 0xFF) {
|
||||
break;
|
||||
}
|
||||
|
||||
int p = (((b2 & 0x1F) << 8) + b1) >> 1;
|
||||
|
||||
int x = p % 64;
|
||||
int y = p >> 6;
|
||||
|
||||
int fakeID = i;
|
||||
if (fakeID >= 64) {
|
||||
fakeID -= 64;
|
||||
}
|
||||
|
||||
int sy = fakeID / 8;
|
||||
int sx = fakeID - (sy * 8);
|
||||
|
||||
all_items_.emplace_back(zelda3::OverworldItem(
|
||||
b3, (ushort)i, (x * 16) + (sx * 512), (y * 16) + (sy * 512), false));
|
||||
auto size = all_items_.size();
|
||||
all_items_.at(size - 1).game_x = (uint8_t)x;
|
||||
all_items_.at(size - 1).game_y = (uint8_t)y;
|
||||
addr += 3;
|
||||
}
|
||||
}
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void Overworld::LoadSprites() {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
all_sprites_.emplace_back();
|
||||
@@ -1025,7 +1156,7 @@ void Overworld::LoadSpritesFromMap(int sprite_start, int sprite_count,
|
||||
|
||||
int ptrPos = sprite_start + (i * 2);
|
||||
int sprite_address =
|
||||
core::SnesToPc((0x09 << 0x10) + rom()->toint16(ptrPos));
|
||||
core::SnesToPc((0x09 << 0x10) | rom()->toint16(ptrPos));
|
||||
while (true) {
|
||||
uchar b1 = rom_[sprite_address];
|
||||
uchar b2 = rom_[sprite_address + 1];
|
||||
@@ -1033,20 +1164,20 @@ void Overworld::LoadSpritesFromMap(int sprite_start, int sprite_count,
|
||||
if (b1 == 0xFF) break;
|
||||
|
||||
int editor_map_index = i;
|
||||
if (editor_map_index >= 128)
|
||||
editor_map_index -= 128;
|
||||
else if (editor_map_index >= 64)
|
||||
editor_map_index -= 64;
|
||||
|
||||
if (sprite_index != 0) {
|
||||
if (editor_map_index >= 128)
|
||||
editor_map_index -= 128;
|
||||
else if (editor_map_index >= 64)
|
||||
editor_map_index -= 64;
|
||||
}
|
||||
int mapY = (editor_map_index / 8);
|
||||
int mapX = (editor_map_index % 8);
|
||||
|
||||
int realX = ((b2 & 0x3F) * 16) + mapX * 512;
|
||||
int realY = ((b1 & 0x3F) * 16) + mapY * 512;
|
||||
auto graphics_bytes = overworld_maps_[i].AreaGraphics();
|
||||
all_sprites_[sprite_index][i].InitSprite(
|
||||
graphics_bytes, (uchar)i, b3, (uchar)(b2 & 0x3F), (uchar)(b1 & 0x3F),
|
||||
realX, realY);
|
||||
overworld_maps_[i].AreaGraphics(), (uchar)i, b3, (uchar)(b2 & 0x3F),
|
||||
(uchar)(b1 & 0x3F), realX, realY);
|
||||
all_sprites_[sprite_index][i].Draw();
|
||||
|
||||
sprite_address += 3;
|
||||
@@ -1133,8 +1264,6 @@ absl::Status Overworld::LoadPrototype(ROM &rom,
|
||||
}
|
||||
}
|
||||
|
||||
// LoadSprites();
|
||||
|
||||
is_loaded_ = true;
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,143 @@ namespace yaze {
|
||||
namespace app {
|
||||
namespace zelda3 {
|
||||
|
||||
class OverworldEntity {
|
||||
public:
|
||||
enum EntityType {
|
||||
kEntrance = 0,
|
||||
kExit = 1,
|
||||
kItem = 2,
|
||||
kSprite = 3,
|
||||
kTransport = 4,
|
||||
kMusic = 5,
|
||||
kTilemap = 6,
|
||||
kProperties = 7
|
||||
} type_;
|
||||
int x_;
|
||||
int y_;
|
||||
int game_x_;
|
||||
int game_y_;
|
||||
int entity_id_;
|
||||
int map_id_;
|
||||
|
||||
auto set_x(int x) { x_ = x; }
|
||||
auto set_y(int y) { y_ = y; }
|
||||
|
||||
OverworldEntity() = default;
|
||||
|
||||
virtual void UpdateMapProperties(short map_id) = 0;
|
||||
};
|
||||
|
||||
// List of secret item names
|
||||
const std::vector<std::string> kSecretItemNames = {
|
||||
"Nothing", // 0
|
||||
"Green Rupee", // 1
|
||||
"Rock hoarder", // 2
|
||||
"Bee", // 3
|
||||
"Health pack", // 4
|
||||
"Bomb", // 5
|
||||
"Heart ", // 6
|
||||
"Blue Rupee", // 7
|
||||
"Key", // 8
|
||||
"Arrow", // 9
|
||||
"Bomb", // 10
|
||||
"Heart", // 11
|
||||
"Magic", // 12
|
||||
"Full Magic", // 13
|
||||
"Cucco", // 14
|
||||
"Green Soldier", // 15
|
||||
"Bush Stal", // 16
|
||||
"Blue Soldier", // 17
|
||||
"Landmine", // 18
|
||||
"Heart", // 19
|
||||
"Fairy", // 20
|
||||
"Heart", // 21
|
||||
"Nothing ", // 22
|
||||
"Hole", // 23
|
||||
"Warp", // 24
|
||||
"Staircase", // 25
|
||||
"Bombable", // 26
|
||||
"Switch" // 27
|
||||
};
|
||||
|
||||
constexpr int overworldItemsPointers = 0xDC2F9;
|
||||
constexpr int overworldItemsAddress = 0xDC8B9; // 1BC2F9
|
||||
constexpr int overworldItemsBank = 0xDC8BF;
|
||||
constexpr int overworldItemsEndData = 0xDC89C; // 0DC89E
|
||||
|
||||
class OverworldItem : public OverworldEntity {
|
||||
public:
|
||||
bool bg2 = false;
|
||||
uint8_t game_x;
|
||||
uint8_t game_y;
|
||||
uint8_t id;
|
||||
uint16_t room_map_id;
|
||||
int unique_id = 0;
|
||||
bool deleted = false;
|
||||
OverworldItem() = default;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OverworldItem"/>
|
||||
/// class.
|
||||
/// </summary>
|
||||
/// <param name="id"> The ID. </param>
|
||||
/// <param name="room_map_id"> The dungeon room ID or overworld area ID.
|
||||
/// </param> <param name="x"> The in editor X position. </param> <param
|
||||
/// name="y"> The in editor Y position. </param> <param name="bg2"> Whether
|
||||
/// the Item is on BG2 or not. </param>
|
||||
OverworldItem(uint8_t id, uint16_t room_map_id, int x, int y, bool bg2) {
|
||||
this->id = id;
|
||||
this->x_ = x;
|
||||
this->y_ = y;
|
||||
this->bg2 = bg2;
|
||||
this->room_map_id = room_map_id;
|
||||
this->map_id_ = room_map_id;
|
||||
this->entity_id_ = id;
|
||||
this->type_ = kItem;
|
||||
|
||||
int map_x = room_map_id - ((room_map_id / 8) * 8);
|
||||
int map_y = room_map_id / 8;
|
||||
|
||||
this->game_x = static_cast<uint8_t>(std::abs(x - (map_x * 512)) / 16);
|
||||
this->game_y = static_cast<uint8_t>(std::abs(y - (map_y * 512)) / 16);
|
||||
// this->unique_id = ROM.unique_item_id++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the item info when needed. Generally when moving items around
|
||||
/// in editor.
|
||||
/// </summary>
|
||||
/// <param name="room_map_id"> The dungeon room ID or overworld area ID where
|
||||
/// the item was moved to. </param>
|
||||
void UpdateMapProperties(int16_t room_map_id) override {
|
||||
this->room_map_id = static_cast<uint16_t>(room_map_id);
|
||||
|
||||
if (room_map_id >= 64) {
|
||||
room_map_id -= 64;
|
||||
}
|
||||
|
||||
int map_x = room_map_id - ((room_map_id / 8) * 8);
|
||||
int map_y = room_map_id / 8;
|
||||
|
||||
this->game_x =
|
||||
static_cast<uint8_t>(std::abs(this->x_ - (map_x * 512)) / 16);
|
||||
this->game_y =
|
||||
static_cast<uint8_t>(std::abs(this->y_ - (map_y * 512)) / 16);
|
||||
|
||||
std::cout << "Item: " << std::hex << std::setw(2) << std::setfill('0')
|
||||
<< static_cast<int>(this->id) << " MapId: " << std::hex
|
||||
<< std::setw(2) << std::setfill('0')
|
||||
<< static_cast<int>(this->room_map_id)
|
||||
<< " X: " << static_cast<int>(this->game_x)
|
||||
<< " Y: " << static_cast<int>(this->game_y) << std::endl;
|
||||
}
|
||||
|
||||
OverworldItem Copy() {
|
||||
return OverworldItem(this->id, this->room_map_id, this->x_, this->y_,
|
||||
this->bg2);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr int OWExitRoomId = 0x15D8A; // 0x15E07 Credits sequences
|
||||
// 105C2 Ending maps
|
||||
// 105E2 Sprite Group Table for Ending
|
||||
@@ -50,10 +187,8 @@ constexpr int OWExitUnk1Whirlpool = 0x16BF5; // JP = ;016E91
|
||||
constexpr int OWExitUnk2Whirlpool = 0x16C17; // JP = ;016EB3
|
||||
constexpr int OWWhirlpoolPosition = 0x16CF8; // JP = ;016F94
|
||||
|
||||
class OverworldExit {
|
||||
class OverworldExit : public OverworldEntity {
|
||||
public:
|
||||
int x_;
|
||||
int y_;
|
||||
ushort y_scroll_;
|
||||
ushort x_scroll_;
|
||||
uchar y_player_;
|
||||
@@ -69,23 +204,21 @@ class OverworldExit {
|
||||
uchar entrance_id_;
|
||||
uchar area_x_;
|
||||
uchar area_y_;
|
||||
short map_id_;
|
||||
bool is_hole_ = false;
|
||||
bool deleted = false;
|
||||
bool is_automatic_ = false;
|
||||
bool large_map_ = false;
|
||||
|
||||
OverworldExit() = default;
|
||||
OverworldExit(ushort room_id, uchar map_id, ushort vram_location,
|
||||
ushort y_scroll, ushort x_scroll, ushort player_y,
|
||||
ushort player_x, ushort camera_y, ushort camera_x,
|
||||
uchar scroll_mod_y, uchar scroll_mod_x, ushort door_type_1,
|
||||
ushort door_type_2)
|
||||
: x_(player_x),
|
||||
y_(player_y),
|
||||
map_pos_(vram_location),
|
||||
: map_pos_(vram_location),
|
||||
entrance_id_(0),
|
||||
area_x_(0),
|
||||
area_y_(0),
|
||||
map_id_(map_id),
|
||||
is_hole_(false),
|
||||
room_id_(room_id),
|
||||
y_scroll_(y_scroll),
|
||||
@@ -98,6 +231,12 @@ class OverworldExit {
|
||||
scroll_mod_x_(scroll_mod_x),
|
||||
door_type_1_(door_type_1),
|
||||
door_type_2_(door_type_2) {
|
||||
// Initialize entity variables
|
||||
this->x_ = player_x;
|
||||
this->y_ = player_y;
|
||||
this->map_id_ = map_id;
|
||||
this->type_ = kExit;
|
||||
|
||||
int mapX = (map_id_ - ((map_id_ / 8) * 8));
|
||||
int mapY = (map_id_ / 8);
|
||||
|
||||
@@ -130,14 +269,14 @@ class OverworldExit {
|
||||
}
|
||||
|
||||
// Overworld overworld
|
||||
void UpdateMapProperties(uchar map_id, bool large_map = false) {
|
||||
void UpdateMapProperties(short map_id) override {
|
||||
map_id_ = map_id;
|
||||
|
||||
int large = 256;
|
||||
int mapid = map_id;
|
||||
|
||||
if (map_id < 128) {
|
||||
large = large_map ? 768 : 256;
|
||||
large = large_map_ ? 768 : 256;
|
||||
// if (overworld.overworld_map(map_id)->Parent() != map_id) {
|
||||
// mapid = overworld.overworld_map(map_id)->Parent();
|
||||
// }
|
||||
@@ -223,29 +362,27 @@ constexpr int OWHoleArea = 0xDB826;
|
||||
//(0x13 entries, 1 byte each) corresponding entrance numbers
|
||||
constexpr int OWHoleEntrance = 0xDB84C;
|
||||
|
||||
class OverworldEntrance {
|
||||
class OverworldEntrance : public OverworldEntity {
|
||||
public:
|
||||
int x_;
|
||||
int y_;
|
||||
ushort map_pos_;
|
||||
uchar entrance_id_;
|
||||
uchar area_x_;
|
||||
uchar area_y_;
|
||||
short map_id_;
|
||||
bool is_hole_ = false;
|
||||
bool deleted = false;
|
||||
|
||||
OverworldEntrance() = default;
|
||||
OverworldEntrance(int x, int y, uchar entrance_id, short map_id,
|
||||
ushort map_pos, bool hole)
|
||||
: x_(x),
|
||||
y_(y),
|
||||
map_pos_(map_pos),
|
||||
entrance_id_(entrance_id),
|
||||
map_id_(map_id),
|
||||
is_hole_(hole) {
|
||||
: map_pos_(map_pos), entrance_id_(entrance_id), is_hole_(hole) {
|
||||
x_ = x;
|
||||
y_ = y;
|
||||
map_id_ = map_id;
|
||||
entity_id_ = entrance_id;
|
||||
type_ = kEntrance;
|
||||
|
||||
int mapX = (map_id_ - ((map_id_ / 8) * 8));
|
||||
int mapY = (map_id_ / 8);
|
||||
|
||||
area_x_ = (uchar)((std::abs(x - (mapX * 512)) / 16));
|
||||
area_y_ = (uchar)((std::abs(y - (mapY * 512)) / 16));
|
||||
}
|
||||
@@ -255,7 +392,7 @@ class OverworldEntrance {
|
||||
is_hole_);
|
||||
}
|
||||
|
||||
void UpdateMapProperties(short map_id) {
|
||||
void UpdateMapProperties(short map_id) override {
|
||||
map_id_ = map_id;
|
||||
|
||||
if (map_id_ >= 64) {
|
||||
@@ -289,10 +426,6 @@ constexpr int overworldSpecialPALGroup = 0x16831;
|
||||
constexpr int overworldSpritesBegining = 0x4C881;
|
||||
constexpr int overworldSpritesAgahnim = 0x4CA21;
|
||||
constexpr int overworldSpritesZelda = 0x4C901;
|
||||
constexpr int overworldItemsPointers = 0xDC2F9;
|
||||
constexpr int overworldItemsAddress = 0xDC8B9; // 1BC2F9
|
||||
constexpr int overworldItemsBank = 0xDC8BF;
|
||||
constexpr int overworldItemsEndData = 0xDC89C; // 0DC89E
|
||||
constexpr int mapGfx = 0x7C9C;
|
||||
constexpr int overlayPointers = 0x77664;
|
||||
constexpr int overlayPointersBank = 0x0E;
|
||||
@@ -353,6 +486,7 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
|
||||
absl::Status SaveLargeMaps();
|
||||
absl::Status SaveEntrances();
|
||||
absl::Status SaveExits();
|
||||
absl::Status SaveItems();
|
||||
|
||||
bool CreateTile32Tilemap(bool onlyShow = false);
|
||||
absl::Status SaveMap16Tiles();
|
||||
@@ -368,10 +502,14 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
|
||||
std::vector<gfx::Tile16> tiles16() const { return tiles16_; }
|
||||
|
||||
auto Sprites(int state) const { return all_sprites_[state]; }
|
||||
auto mutable_sprites(int state) { return &all_sprites_[state]; }
|
||||
auto AreaGraphics() const {
|
||||
return overworld_maps_[current_map_].AreaGraphics();
|
||||
}
|
||||
auto &Entrances() { return all_entrances_; }
|
||||
auto mutable_entrances() { return &all_entrances_; }
|
||||
auto &holes() { return all_holes_; }
|
||||
auto mutable_holes() { return &all_holes_; }
|
||||
auto AreaPalette() const {
|
||||
return overworld_maps_[current_map_].AreaPalette();
|
||||
}
|
||||
@@ -387,6 +525,9 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
|
||||
|
||||
auto map_tiles() const { return map_tiles_; }
|
||||
auto mutable_map_tiles() { return &map_tiles_; }
|
||||
auto all_items() const { return all_items_; }
|
||||
auto mutable_all_items() { return &all_items_; }
|
||||
auto &ref_all_items() { return all_items_; }
|
||||
|
||||
absl::Status LoadPrototype(ROM &rom_, const std::string &tilemap_filename);
|
||||
|
||||
@@ -410,6 +551,7 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
|
||||
void FetchLargeMaps();
|
||||
void LoadEntrances();
|
||||
void LoadExits();
|
||||
absl::Status LoadItems();
|
||||
void LoadSprites();
|
||||
void LoadSpritesFromMap(int spriteStart, int spriteCount, int spriteIndex);
|
||||
|
||||
@@ -429,6 +571,7 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
|
||||
std::vector<OverworldEntrance> all_entrances_;
|
||||
std::vector<OverworldEntrance> all_holes_;
|
||||
std::vector<OverworldExit> all_exits_;
|
||||
std::vector<OverworldItem> all_items_;
|
||||
std::vector<std::vector<Sprite>> all_sprites_;
|
||||
|
||||
std::vector<absl::flat_hash_map<uint16_t, int>> usage_stats_;
|
||||
|
||||
@@ -301,6 +301,37 @@ void OverworldMap::LoadMainBlocksets() {
|
||||
}
|
||||
}
|
||||
|
||||
// For animating water tiles on the overworld map.
|
||||
// We want to swap out static_graphics_[07] with the next sheet
|
||||
// Usually it is 5A, so we make it 5B instead.
|
||||
// There is a middle frame which contains tiles from the bottom half
|
||||
// of the 5A sheet, so this will need some special manipulation to make work
|
||||
// during the BuildBitmap step (or a new one specifically for animating).
|
||||
void OverworldMap::DrawAnimatedTiles() {
|
||||
std::cout << "static_graphics_[6] = "
|
||||
<< core::UppercaseHexByte(static_graphics_[6]) << std::endl;
|
||||
std::cout << "static_graphics_[7] = "
|
||||
<< core::UppercaseHexByte(static_graphics_[7]) << std::endl;
|
||||
std::cout << "static_graphics_[8] = "
|
||||
<< core::UppercaseHexByte(static_graphics_[8]) << std::endl;
|
||||
if (static_graphics_[7] == 0x5B) {
|
||||
static_graphics_[7] = 0x5A;
|
||||
} else {
|
||||
if (static_graphics_[7] == 0x59) {
|
||||
static_graphics_[7] = 0x58;
|
||||
}
|
||||
static_graphics_[7] = 0x5B;
|
||||
}
|
||||
// if (static_graphics_[7] == 0x5A) {
|
||||
// static_graphics_[7] = 0x5B;
|
||||
// } else {
|
||||
// if (static_graphics_[7] == 0x58) {
|
||||
// static_graphics_[7] = 0x59;
|
||||
// }
|
||||
// static_graphics_[7] = 0x5A;
|
||||
// }
|
||||
}
|
||||
|
||||
void OverworldMap::LoadAreaGraphicsBlocksets() {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uchar value = rom_[rom_.version_constants().kOverworldGfxGroups1 +
|
||||
|
||||
@@ -36,6 +36,8 @@ class OverworldMap {
|
||||
absl::Status BuildTiles16Gfx(int count);
|
||||
absl::Status BuildBitmap(OWBlockset& world_blockset);
|
||||
|
||||
void DrawAnimatedTiles();
|
||||
|
||||
auto Tile16Blockset() const { return current_blockset_; }
|
||||
auto AreaGraphics() const { return current_gfx_; }
|
||||
auto AreaPalette() const { return current_palette_; }
|
||||
|
||||
@@ -43,13 +43,18 @@ class Sprite {
|
||||
auto y() const { return y_; }
|
||||
auto nx() const { return nx_; }
|
||||
auto ny() const { return ny_; }
|
||||
auto map_id() const { return map_id_; }
|
||||
auto map_x() const { return map_x_; }
|
||||
auto map_y() const { return map_y_; }
|
||||
|
||||
auto layer() const { return layer_; }
|
||||
auto subtype() const { return subtype_; }
|
||||
auto& keyDrop() const { return key_drop_; }
|
||||
|
||||
auto Width() const { return bounding_box_.w; }
|
||||
auto Height() const { return bounding_box_.h; }
|
||||
std::string Name() const { return name_; }
|
||||
std::string& Name() { return name_; }
|
||||
auto deleted() const { return deleted_; }
|
||||
|
||||
private:
|
||||
Bytes current_gfx_;
|
||||
@@ -80,6 +85,8 @@ class Sprite {
|
||||
int height_ = 16;
|
||||
|
||||
int key_drop_;
|
||||
|
||||
bool deleted_ = false;
|
||||
};
|
||||
|
||||
} // namespace zelda3
|
||||
|
||||
Reference in New Issue
Block a user