OverworldExit updates and refactoring
This commit is contained in:
@@ -316,6 +316,8 @@ void OverworldEditor::DrawOverworldEntrances(ImVec2 canvas_p0,
|
||||
canvas_p0.y + scrolling.y);
|
||||
dragged_entrance_->x_ = io.MousePos.x - origin.x - 8;
|
||||
dragged_entrance_->y_ = io.MousePos.y - origin.y - 8;
|
||||
each.x_ = dragged_entrance_->x_;
|
||||
each.y_ = dragged_entrance_->y_;
|
||||
is_dragging_entrance_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,6 +340,14 @@ class ROM : public core::ExperimentFlags {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status WriteByte(int addr, uint8_t value) {
|
||||
if (addr >= rom_data_.size()) {
|
||||
return absl::InvalidArgumentError("Address out of range");
|
||||
}
|
||||
rom_data_[addr] = value;
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status WriteShort(uint32_t addr, uint16_t value) {
|
||||
if (addr + 1 >= rom_data_.size()) {
|
||||
return absl::InvalidArgumentError("Address out of range");
|
||||
|
||||
@@ -150,17 +150,16 @@ absl::Status Overworld::Load(ROM &rom) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
OWBlockset &Overworld::GetMapTiles(int world_type) {
|
||||
switch (world_type) {
|
||||
case 0:
|
||||
return map_tiles_.light_world;
|
||||
case 1:
|
||||
return map_tiles_.dark_world;
|
||||
case 2:
|
||||
return map_tiles_.special_world;
|
||||
default:
|
||||
return map_tiles_.light_world;
|
||||
}
|
||||
absl::Status Overworld::Save(ROM &rom) {
|
||||
rom_ = rom;
|
||||
|
||||
RETURN_IF_ERROR(SaveMap16Tiles())
|
||||
RETURN_IF_ERROR(SaveMap32Tiles())
|
||||
RETURN_IF_ERROR(SaveOverworldMaps())
|
||||
RETURN_IF_ERROR(SaveEntrances())
|
||||
RETURN_IF_ERROR(SaveExits())
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status Overworld::LoadOverworldMaps() {
|
||||
@@ -300,13 +299,13 @@ absl::Status Overworld::SaveLargeMaps() {
|
||||
int parentyPos = overworld_maps_[i].Parent() / 8;
|
||||
int parentxPos = overworld_maps_[i].Parent() % 8;
|
||||
|
||||
std::unordered_map<uint8_t, uint8_t> checkedMap;
|
||||
std::unordered_map<uint8_t, uint8_t> checked_map;
|
||||
|
||||
// Always write the map parent since it should not matter
|
||||
RETURN_IF_ERROR(
|
||||
rom()->Write(overworldMapParentId + i, overworld_maps_[i].Parent()))
|
||||
|
||||
if (checkedMap.count(overworld_maps_[i].Parent()) > 0) {
|
||||
if (checked_map.count(overworld_maps_[i].Parent()) > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -404,20 +403,20 @@ absl::Status Overworld::SaveLargeMaps() {
|
||||
WriteAction{OverworldScreenTileMapChangeByScreen + (i * 2) + 2,
|
||||
0x0060}))
|
||||
|
||||
uint16_t lowerSubmaps;
|
||||
uint16_t lower_submaps;
|
||||
// If parentX == 0 then lower submaps == 0x0060 too
|
||||
if (parentxPos == 0) {
|
||||
lowerSubmaps = 0x0060;
|
||||
lower_submaps = 0x0060;
|
||||
} else {
|
||||
// Otherwise lower submaps == 0x1060
|
||||
lowerSubmaps = 0x1060;
|
||||
lower_submaps = 0x1060;
|
||||
}
|
||||
|
||||
RETURN_IF_ERROR(rom()->RunTransaction(
|
||||
WriteAction{OverworldScreenTileMapChangeByScreen + (i * 2) + 16,
|
||||
uint16_t(lowerSubmaps)},
|
||||
uint16_t(lower_submaps)},
|
||||
WriteAction{OverworldScreenTileMapChangeByScreen + (i * 2) + 18,
|
||||
uint16_t(lowerSubmaps)},
|
||||
uint16_t(lower_submaps)},
|
||||
WriteAction{OverworldScreenTileMapChangeByScreen + (i * 2) + 128,
|
||||
uint16_t(0x0080)}, // Always 0x0080
|
||||
WriteAction{OverworldScreenTileMapChangeByScreen + (i * 2) + 2 + 128,
|
||||
@@ -448,10 +447,10 @@ absl::Status Overworld::SaveLargeMaps() {
|
||||
WriteAction{OverworldScreenTileMapChangeByScreen + (i * 2) + 18 + 384,
|
||||
uint16_t(0x2040)})) // Always 0x2000
|
||||
|
||||
checkedMap.emplace(i, 1);
|
||||
checkedMap.emplace((i + 1), 1);
|
||||
checkedMap.emplace((i + 8), 1);
|
||||
checkedMap.emplace((i + 9), 1);
|
||||
checked_map.emplace(i, 1);
|
||||
checked_map.emplace((i + 1), 1);
|
||||
checked_map.emplace((i + 8), 1);
|
||||
checked_map.emplace((i + 9), 1);
|
||||
|
||||
} else {
|
||||
RETURN_IF_ERROR(rom()->RunTransaction(
|
||||
@@ -480,7 +479,7 @@ absl::Status Overworld::SaveLargeMaps() {
|
||||
WriteAction{overworldTransitionPositionY + (i * 2),
|
||||
uint16_t(yPos * 0x200)}))
|
||||
|
||||
checkedMap.emplace(i, 1);
|
||||
checked_map.emplace(i, 1);
|
||||
}
|
||||
}
|
||||
return absl::OkStatus();
|
||||
@@ -862,82 +861,140 @@ void Overworld::FetchLargeMaps() {
|
||||
|
||||
void Overworld::LoadEntrances() {
|
||||
for (int i = 0; i < 129; i++) {
|
||||
short mapId = rom()->toint16(OWEntranceMap + (i * 2));
|
||||
ushort mapPos = rom()->toint16(OWEntrancePos + (i * 2));
|
||||
uchar entranceId = (rom_[OWEntranceEntranceId + i]);
|
||||
int p = mapPos >> 1;
|
||||
short map_id = rom()->toint16(OWEntranceMap + (i * 2));
|
||||
ushort map_pos = rom()->toint16(OWEntrancePos + (i * 2));
|
||||
uchar entrance_id = rom_[OWEntranceEntranceId + i];
|
||||
int p = map_pos >> 1;
|
||||
int x = (p % 64);
|
||||
int y = (p >> 6);
|
||||
bool deleted = false;
|
||||
if (mapPos == 0xFFFF) {
|
||||
if (map_pos == 0xFFFF) {
|
||||
deleted = true;
|
||||
}
|
||||
all_entrances_.emplace_back(
|
||||
(x * 16) + (((mapId % 64) - (((mapId % 64) / 8) * 8)) * 512),
|
||||
(y * 16) + (((mapId % 64) / 8) * 512), entranceId, mapId, mapPos,
|
||||
(x * 16) + (((map_id % 64) - (((map_id % 64) / 8) * 8)) * 512),
|
||||
(y * 16) + (((map_id % 64) / 8) * 512), entrance_id, map_id, map_pos,
|
||||
deleted);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 0x13; i++) {
|
||||
auto mapId = (short)((rom_[OWHoleArea + (i * 2) + 1] << 8) +
|
||||
(rom_[OWHoleArea + (i * 2)]));
|
||||
auto mapPos = (short)((rom_[OWHolePos + (i * 2) + 1] << 8) +
|
||||
(rom_[OWHolePos + (i * 2)]));
|
||||
uchar entranceId = (rom_[OWHoleEntrance + i]);
|
||||
int p = (mapPos + 0x400) >> 1;
|
||||
auto map_id = (short)((rom_[OWHoleArea + (i * 2) + 1] << 8) +
|
||||
(rom_[OWHoleArea + (i * 2)]));
|
||||
auto map_pos = (short)((rom_[OWHolePos + (i * 2) + 1] << 8) +
|
||||
(rom_[OWHolePos + (i * 2)]));
|
||||
uchar entrance_id = (rom_[OWHoleEntrance + i]);
|
||||
int p = (map_pos + 0x400) >> 1;
|
||||
int x = (p % 64);
|
||||
int y = (p >> 6);
|
||||
all_holes_.emplace_back(
|
||||
(x * 16) + (((mapId % 64) - (((mapId % 64) / 8) * 8)) * 512),
|
||||
(y * 16) + (((mapId % 64) / 8) * 512), entranceId, mapId,
|
||||
(ushort)(mapPos + 0x400), true);
|
||||
(x * 16) + (((map_id % 64) - (((map_id % 64) / 8) * 8)) * 512),
|
||||
(y * 16) + (((map_id % 64) / 8) * 512), entrance_id, map_id,
|
||||
(ushort)(map_pos + 0x400), true);
|
||||
}
|
||||
}
|
||||
|
||||
absl::Status Overworld::SaveEntrances() {
|
||||
for (int i = 0; i < 129; i++) {
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWEntranceMap + (i * 2), all_entrances_[i].map_id_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWEntrancePos + (i * 2), all_entrances_[i].map_pos_))
|
||||
RETURN_IF_ERROR(rom()->WriteByte(OWEntranceEntranceId + i,
|
||||
all_entrances_[i].entrance_id_))
|
||||
}
|
||||
|
||||
for (int i = 0; i < 0x13; i++) {
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWHoleArea + (i * 2), all_holes_[i].map_id_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWHolePos + (i * 2), all_holes_[i].map_pos_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteByte(OWHoleEntrance + i, all_holes_[i].entrance_id_))
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status Overworld::SaveExits() {
|
||||
for (int i = 0; i < 0x4F; i++) {
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWExitRoomId + (i * 2), all_exits_[i].room_id_))
|
||||
RETURN_IF_ERROR(rom()->WriteByte(OWExitMapId + i, all_exits_[i].map_id_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWExitVram + (i * 2), all_exits_[i].map_pos_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWExitYScroll + (i * 2), all_exits_[i].y_scroll_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWExitXScroll + (i * 2), all_exits_[i].x_scroll_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWExitYPlayer + (i * 2), all_exits_[i].y_player_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWExitXPlayer + (i * 2), all_exits_[i].x_player_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWExitYCamera + (i * 2), all_exits_[i].y_camera_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteShort(OWExitXCamera + (i * 2), all_exits_[i].x_camera_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteByte(OWExitUnk1 + i, all_exits_[i].scroll_mod_y_))
|
||||
RETURN_IF_ERROR(
|
||||
rom()->WriteByte(OWExitUnk2 + i, all_exits_[i].scroll_mod_x_))
|
||||
RETURN_IF_ERROR(rom()->WriteShort(OWExitDoorType1 + (i * 2),
|
||||
all_exits_[i].door_type_1_))
|
||||
RETURN_IF_ERROR(rom()->WriteShort(OWExitDoorType2 + (i * 2),
|
||||
all_exits_[i].door_type_2_))
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void Overworld::LoadExits() {
|
||||
const int NumberOfOverworldExits = 0x4F;
|
||||
std::vector<OverworldExit> exits;
|
||||
for (int i = 0; i < NumberOfOverworldExits; i++) {
|
||||
auto rom_data = rom()->data();
|
||||
ushort exitRoomID = (ushort)((rom_data[OWExitRoomId + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitRoomId + (i * 2)]);
|
||||
ushort exitMapID = rom_data[OWExitMapId + i];
|
||||
ushort exitVRAM = (ushort)((rom_data[OWExitVram + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitVram + (i * 2)]);
|
||||
ushort exitYScroll = (ushort)((rom_data[OWExitYScroll + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitYScroll + (i * 2)]);
|
||||
ushort exitXScroll = (ushort)((rom_data[OWExitXScroll + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitXScroll + (i * 2)]);
|
||||
ushort exit_room_id = (ushort)((rom_data[OWExitRoomId + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitRoomId + (i * 2)]);
|
||||
ushort exit_map_id = rom_data[OWExitMapId + i];
|
||||
ushort exit_vram = (ushort)((rom_data[OWExitVram + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitVram + (i * 2)]);
|
||||
ushort exit_y_scroll =
|
||||
(ushort)((rom_data[OWExitYScroll + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitYScroll + (i * 2)]);
|
||||
ushort exit_x_scroll =
|
||||
(ushort)((rom_data[OWExitXScroll + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitXScroll + (i * 2)]);
|
||||
ushort py = (ushort)((rom_data[OWExitYPlayer + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitYPlayer + (i * 2)]);
|
||||
ushort px = (ushort)((rom_data[OWExitXPlayer + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitXPlayer + (i * 2)]);
|
||||
ushort exitYCamera = (ushort)((rom_data[OWExitYCamera + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitYCamera + (i * 2)]);
|
||||
ushort exitXCamera = (ushort)((rom_data[OWExitXCamera + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitXCamera + (i * 2)]);
|
||||
ushort exitScrollModY = rom_data[OWExitUnk1 + i];
|
||||
ushort exitScrollModX = rom_data[OWExitUnk2 + i];
|
||||
ushort exitDoorType1 =
|
||||
ushort exit_y_camera =
|
||||
(ushort)((rom_data[OWExitYCamera + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitYCamera + (i * 2)]);
|
||||
ushort exit_x_camera =
|
||||
(ushort)((rom_data[OWExitXCamera + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitXCamera + (i * 2)]);
|
||||
ushort exit_scroll_mod_y = rom_data[OWExitUnk1 + i];
|
||||
ushort exit_scroll_mod_x = rom_data[OWExitUnk2 + i];
|
||||
ushort exit_door_type_1 =
|
||||
(ushort)((rom_data[OWExitDoorType1 + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitDoorType1 + (i * 2)]);
|
||||
ushort exitDoorType2 =
|
||||
ushort exit_door_type_2 =
|
||||
(ushort)((rom_data[OWExitDoorType2 + (i * 2) + 1] << 8) +
|
||||
rom_data[OWExitDoorType2 + (i * 2)]);
|
||||
OverworldExit exit(exitRoomID, exitMapID, exitVRAM, exitYScroll,
|
||||
exitXScroll, py, px, exitYCamera, exitXCamera,
|
||||
exitScrollModY, exitScrollModX, exitDoorType1,
|
||||
exitDoorType2);
|
||||
OverworldExit exit(exit_room_id, exit_map_id, exit_vram, exit_y_scroll,
|
||||
exit_x_scroll, py, px, exit_y_camera, exit_x_camera,
|
||||
exit_scroll_mod_y, exit_scroll_mod_x, exit_door_type_1,
|
||||
exit_door_type_2);
|
||||
|
||||
std::cout << "Exit: " << i << " RoomID: " << exitRoomID
|
||||
<< " MapID: " << exitMapID << " VRAM: " << exitVRAM
|
||||
<< " YScroll: " << exitYScroll << " XScroll: " << exitXScroll
|
||||
std::cout << "Exit: " << i << " RoomID: " << exit_room_id
|
||||
<< " MapID: " << exit_map_id << " VRAM: " << exit_vram
|
||||
<< " YScroll: " << exit_y_scroll << " XScroll: " << exit_x_scroll
|
||||
<< " YPlayer: " << py << " XPlayer: " << px
|
||||
<< " YCamera: " << exitYCamera << " XCamera: " << exitXCamera
|
||||
<< " ScrollModY: " << exitScrollModY
|
||||
<< " ScrollModX: " << exitScrollModX
|
||||
<< " DoorType1: " << exitDoorType1
|
||||
<< " DoorType2: " << exitDoorType2 << std::endl;
|
||||
<< " YCamera: " << exit_y_camera << " XCamera: " << exit_x_camera
|
||||
<< " ScrollModY: " << exit_scroll_mod_y
|
||||
<< " ScrollModX: " << exit_scroll_mod_x
|
||||
<< " DoorType1: " << exit_door_type_1
|
||||
<< " DoorType2: " << exit_door_type_2 << std::endl;
|
||||
|
||||
if (px == 0xFFFF && py == 0xFFFF) {
|
||||
exit.deleted = true;
|
||||
@@ -1050,6 +1107,19 @@ absl::Status Overworld::LoadPrototype(ROM &rom,
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
OWBlockset &Overworld::GetMapTiles(int world_type) {
|
||||
switch (world_type) {
|
||||
case 0:
|
||||
return map_tiles_.light_world;
|
||||
case 1:
|
||||
return map_tiles_.dark_world;
|
||||
case 2:
|
||||
return map_tiles_.special_world;
|
||||
default:
|
||||
return map_tiles_.light_world;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace zelda3
|
||||
} // namespace app
|
||||
} // namespace yaze
|
||||
@@ -64,8 +64,19 @@ class OverworldExit {
|
||||
public:
|
||||
int x_;
|
||||
int y_;
|
||||
ushort y_scroll_;
|
||||
ushort x_scroll_;
|
||||
uchar y_player_;
|
||||
uchar x_player_;
|
||||
uchar y_camera_;
|
||||
uchar x_camera_;
|
||||
uchar scroll_mod_y_;
|
||||
uchar scroll_mod_x_;
|
||||
ushort door_type_1_;
|
||||
ushort door_type_2_;
|
||||
|
||||
ushort room_id_;
|
||||
ushort map_pos_;
|
||||
ushort map_pos_; // Position in the vram
|
||||
uchar entrance_id_;
|
||||
uchar area_x_;
|
||||
uchar area_y_;
|
||||
@@ -84,7 +95,18 @@ class OverworldExit {
|
||||
area_x_(0),
|
||||
area_y_(0),
|
||||
map_id_(mapID),
|
||||
is_hole_(false) {
|
||||
is_hole_(false),
|
||||
room_id_(roomID),
|
||||
y_scroll_(yScroll),
|
||||
x_scroll_(xScroll),
|
||||
y_player_(playerY),
|
||||
x_player_(playerX),
|
||||
y_camera_(cameraY),
|
||||
x_camera_(cameraX),
|
||||
scroll_mod_y_(scrollModY),
|
||||
scroll_mod_x_(scrollModX),
|
||||
door_type_1_(doorType1),
|
||||
door_type_2_(doorType2) {
|
||||
int mapX = (map_id_ - ((map_id_ / 8) * 8));
|
||||
int mapY = (map_id_ / 8);
|
||||
|
||||
@@ -207,13 +229,13 @@ class OverworldEntrance {
|
||||
bool is_hole_ = false;
|
||||
bool deleted = false;
|
||||
|
||||
OverworldEntrance(int x, int y, uchar entranceId, short mapId, ushort mapPos,
|
||||
bool hole)
|
||||
OverworldEntrance(int x, int y, uchar entrance_id, short map_id,
|
||||
ushort map_pos, bool hole)
|
||||
: x_(x),
|
||||
y_(y),
|
||||
map_pos_(mapPos),
|
||||
entrance_id_(entranceId),
|
||||
map_id_(mapId),
|
||||
map_pos_(map_pos),
|
||||
entrance_id_(entrance_id),
|
||||
map_id_(map_id),
|
||||
is_hole_(hole) {
|
||||
int mapX = (map_id_ - ((map_id_ / 8) * 8));
|
||||
int mapY = (map_id_ / 8);
|
||||
@@ -227,8 +249,8 @@ class OverworldEntrance {
|
||||
is_hole_);
|
||||
}
|
||||
|
||||
void updateMapStuff(short mapId) {
|
||||
map_id_ = mapId;
|
||||
void UpdateMapStuff(short map_id) {
|
||||
map_id_ = map_id;
|
||||
|
||||
if (map_id_ >= 64) {
|
||||
map_id_ -= 64;
|
||||
@@ -317,10 +339,14 @@ struct MapData {
|
||||
class Overworld : public SharedROM, public core::ExperimentFlags {
|
||||
public:
|
||||
absl::Status Load(ROM &rom);
|
||||
absl::Status Save(ROM &rom);
|
||||
OWBlockset &GetMapTiles(int world_type);
|
||||
absl::Status LoadOverworldMaps();
|
||||
|
||||
absl::Status SaveOverworldMaps();
|
||||
absl::Status SaveLargeMaps();
|
||||
absl::Status SaveEntrances();
|
||||
absl::Status SaveExits();
|
||||
|
||||
bool CreateTile32Tilemap(bool onlyShow = false);
|
||||
absl::Status SaveMap16Tiles();
|
||||
@@ -376,10 +402,11 @@ class Overworld : public SharedROM, public core::ExperimentFlags {
|
||||
void LoadSprites();
|
||||
void LoadSpritesFromMap(int spriteStart, int spriteCount, int spriteIndex);
|
||||
|
||||
bool is_loaded_ = false;
|
||||
|
||||
int game_state_ = 0;
|
||||
int current_map_ = 0;
|
||||
uchar map_parent_[160];
|
||||
bool is_loaded_ = false;
|
||||
|
||||
ROM rom_;
|
||||
OWMapTiles map_tiles_;
|
||||
|
||||
Reference in New Issue
Block a user