imgui-frontend-engineer: fix merge blockers in graphics/dungeon map
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
// C++ standard library headers
|
// C++ standard library headers
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
// Third-party library headers
|
// Third-party library headers
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
@@ -209,6 +210,8 @@ absl::Status GraphicsEditor::Save() {
|
|||||||
state_.modified_sheets.size());
|
state_.modified_sheets.size());
|
||||||
|
|
||||||
auto& sheets = gfx::Arena::Get().gfx_sheets();
|
auto& sheets = gfx::Arena::Get().gfx_sheets();
|
||||||
|
std::set<uint16_t> saved_sheets;
|
||||||
|
std::vector<uint16_t> skipped_sheets;
|
||||||
|
|
||||||
for (uint16_t sheet_id : state_.modified_sheets) {
|
for (uint16_t sheet_id : state_.modified_sheets) {
|
||||||
if (sheet_id >= zelda3::kNumGfxSheets) continue;
|
if (sheet_id >= zelda3::kNumGfxSheets) continue;
|
||||||
@@ -230,6 +233,20 @@ absl::Status GraphicsEditor::Save() {
|
|||||||
compressed = false;
|
compressed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bpp == 2) {
|
||||||
|
const size_t expected_size =
|
||||||
|
gfx::kTilesheetWidth * gfx::kTilesheetHeight * 2;
|
||||||
|
const size_t actual_size = sheet.vector().size();
|
||||||
|
if (actual_size < expected_size) {
|
||||||
|
LOG_WARN(
|
||||||
|
"GraphicsEditor",
|
||||||
|
"Skipping 2BPP sheet %02X save (expected %zu bytes, got %zu)",
|
||||||
|
sheet_id, expected_size, actual_size);
|
||||||
|
skipped_sheets.push_back(sheet_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate ROM offset for this sheet
|
// Calculate ROM offset for this sheet
|
||||||
// Get version constants from game_data
|
// Get version constants from game_data
|
||||||
auto version_constants = zelda3::kVersionConstantsMap.at(game_data()->version);
|
auto version_constants = zelda3::kVersionConstantsMap.at(game_data()->version);
|
||||||
@@ -288,10 +305,16 @@ absl::Status GraphicsEditor::Save() {
|
|||||||
LOG_INFO("GraphicsEditor", "Saved sheet %02X (%zu bytes, %s) at offset %06X",
|
LOG_INFO("GraphicsEditor", "Saved sheet %02X (%zu bytes, %s) at offset %06X",
|
||||||
sheet_id, final_data.size(), compressed ? "compressed" : "raw",
|
sheet_id, final_data.size(), compressed ? "compressed" : "raw",
|
||||||
offset);
|
offset);
|
||||||
|
saved_sheets.insert(sheet_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear modified tracking after successful save
|
// Clear modified tracking after successful save
|
||||||
state_.ClearModifiedSheets();
|
state_.ClearModifiedSheets(saved_sheets);
|
||||||
|
if (!skipped_sheets.empty()) {
|
||||||
|
return absl::FailedPreconditionError(
|
||||||
|
absl::StrCat("Skipped ", skipped_sheets.size(),
|
||||||
|
" 2BPP sheet(s); full data unavailable."));
|
||||||
|
}
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,6 +139,15 @@ class GraphicsEditorState {
|
|||||||
*/
|
*/
|
||||||
void ClearModifiedSheets() { modified_sheets.clear(); }
|
void ClearModifiedSheets() { modified_sheets.clear(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clear specific sheets from modification tracking
|
||||||
|
*/
|
||||||
|
void ClearModifiedSheets(const std::set<uint16_t>& sheet_ids) {
|
||||||
|
for (auto sheet_id : sheet_ids) {
|
||||||
|
modified_sheets.erase(sheet_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if any sheets have unsaved changes
|
* @brief Check if any sheets have unsaved changes
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -414,6 +414,7 @@ absl::StatusOr<AsarPatchResult> AsarWrapper::ApplyPatchWithBinary(
|
|||||||
FILE* pipe = popen(cmd.str().c_str(), "r");
|
FILE* pipe = popen(cmd.str().c_str(), "r");
|
||||||
if (!pipe) {
|
if (!pipe) {
|
||||||
fs::remove(temp_rom, ec);
|
fs::remove(temp_rom, ec);
|
||||||
|
fs::remove(temp_symbols, ec);
|
||||||
if (!patch_dir.empty()) fs::current_path(original_cwd, ec);
|
if (!patch_dir.empty()) fs::current_path(original_cwd, ec);
|
||||||
return absl::InternalError("popen() failed for Asar CLI");
|
return absl::InternalError("popen() failed for Asar CLI");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,8 +93,10 @@ absl::Status SaveDungeonMaps(Rom& rom, std::vector<DungeonMap>& dungeon_maps) {
|
|||||||
RETURN_IF_ERROR(rom.WriteWord(kDungeonMapBossRooms + (d * 2),
|
RETURN_IF_ERROR(rom.WriteWord(kDungeonMapBossRooms + (d * 2),
|
||||||
map.boss_room));
|
map.boss_room));
|
||||||
|
|
||||||
bool search_boss = map.boss_room != 0x000F;
|
const bool has_boss =
|
||||||
if (!search_boss) {
|
map.boss_room != 0x000F && map.boss_room != 0xFFFF;
|
||||||
|
bool search_boss = has_boss;
|
||||||
|
if (!has_boss) {
|
||||||
RETURN_IF_ERROR(
|
RETURN_IF_ERROR(
|
||||||
rom.WriteWord(kDungeonMapBossFloors + (d * 2), 0xFFFF));
|
rom.WriteWord(kDungeonMapBossFloors + (d * 2), 0xFFFF));
|
||||||
}
|
}
|
||||||
@@ -111,15 +113,15 @@ absl::Status SaveDungeonMaps(Rom& rom, std::vector<DungeonMap>& dungeon_maps) {
|
|||||||
search_boss = false;
|
search_boss = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_IF_ERROR(rom.WriteByte(pos, map.floor_rooms[f][r]));
|
|
||||||
pos++;
|
|
||||||
|
|
||||||
if (pos >= kDungeonMapDataReservedStart &&
|
if (pos >= kDungeonMapDataReservedStart &&
|
||||||
pos <= kDungeonMapDataReservedEnd) {
|
pos <= kDungeonMapDataReservedEnd) {
|
||||||
pos = kDungeonMapDataReservedEnd + 1;
|
pos = kDungeonMapDataReservedEnd + 1;
|
||||||
restart = true;
|
restart = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RETURN_IF_ERROR(rom.WriteByte(pos, map.floor_rooms[f][r]));
|
||||||
|
pos++;
|
||||||
}
|
}
|
||||||
if (restart) break;
|
if (restart) break;
|
||||||
}
|
}
|
||||||
@@ -134,9 +136,6 @@ absl::Status SaveDungeonMaps(Rom& rom, std::vector<DungeonMap>& dungeon_maps) {
|
|||||||
for (int f = 0; f < total_floors; f++) {
|
for (int f = 0; f < total_floors; f++) {
|
||||||
for (int r = 0; r < kNumRooms; r++) {
|
for (int r = 0; r < kNumRooms; r++) {
|
||||||
if (map.floor_rooms[f][r] != 0x0F) {
|
if (map.floor_rooms[f][r] != 0x0F) {
|
||||||
RETURN_IF_ERROR(rom.WriteByte(pos, map.floor_gfx[f][r]));
|
|
||||||
pos++;
|
|
||||||
|
|
||||||
if (pos >= kDungeonMapDataReservedStart &&
|
if (pos >= kDungeonMapDataReservedStart &&
|
||||||
pos <= kDungeonMapDataReservedEnd) {
|
pos <= kDungeonMapDataReservedEnd) {
|
||||||
pos = kDungeonMapDataReservedEnd + 1;
|
pos = kDungeonMapDataReservedEnd + 1;
|
||||||
@@ -145,6 +144,9 @@ absl::Status SaveDungeonMaps(Rom& rom, std::vector<DungeonMap>& dungeon_maps) {
|
|||||||
restart = true;
|
restart = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RETURN_IF_ERROR(rom.WriteByte(pos, map.floor_gfx[f][r]));
|
||||||
|
pos++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (restart) break;
|
if (restart) break;
|
||||||
|
|||||||
Reference in New Issue
Block a user