feat(docs): add implementation status for Screen Editor

- Created a comprehensive document detailing the implementation status of the Screen Editor, including sections for Title Screen, Overworld Map, and Dungeon Map editors.
- Document outlines current statuses, functionalities, issues, and next steps for each editor, providing clarity on ongoing development efforts.
- Highlights critical issues with vanilla ROM tilemap loading and outlines priorities for future work.

Benefits:
- Enhances project documentation, aiding developers in understanding the current state and challenges of the Screen Editor.
- Serves as a reference for future development and troubleshooting efforts.
This commit is contained in:
scawful
2025-10-13 21:43:00 -04:00
parent b51f754f52
commit 8c18895ed7
2 changed files with 409 additions and 67 deletions

View File

@@ -337,81 +337,86 @@ absl::Status TitleScreen::LoadTitleScreen(Rom* rom) {
LOG_INFO("TitleScreen", "Loaded 2048 tilemap entries from ZScream expanded format");
}
// Vanilla format with 7 compressed sections
// Vanilla format: Sequential DMA blocks at pointer location
// NOTE: This reads from the pointer but may not be the correct format
// See docs/screen-editor-status.md for details on this ongoing issue
else {
LOG_INFO("TitleScreen", "Using vanilla compressed format");
// Title screen tilemap data is stored in 7 sections
// Each section contains tile words for a portion of the screen
constexpr int kTilemapAddresses[7] = {
0x53de4, 0x53e2c, 0x53e08, 0x53e50, 0x53e74, 0x53e98, 0x53ebc};
LOG_INFO("TitleScreen", "Using vanilla DMA format (EXPERIMENTAL)");
int pos = pc_addr;
int total_entries = 0;
int blocks_read = 0;
// Load each tilemap section
for (int section = 0; section < 7; section++) {
int pos = kTilemapAddresses[section];
// Read compressed tilemap data for this section
// Format: destination address (word), length (word), tile data
while (pos < rom->size()) {
ASSIGN_OR_RETURN(uint8_t first_byte, rom->ReadByte(pos));
if ((first_byte & 0x80) == 0x80) {
break; // End of section marker
}
ASSIGN_OR_RETURN(uint16_t dest_addr, rom->ReadWord(pos));
pos += 2;
ASSIGN_OR_RETURN(uint16_t length_flags, rom->ReadWord(pos));
pos += 2;
bool increment64 = (length_flags & 0x8000) == 0x8000;
bool fixsource = (length_flags & 0x4000) == 0x4000;
int length = (length_flags & 0x07FF);
int posB = pos;
for (int j = 0; j < (length / 2) + 1; j++) {
ASSIGN_OR_RETURN(uint16_t tiledata, rom->ReadWord(pos));
// Determine which layer this tile belongs to
if (dest_addr >= 0x1000 && dest_addr < 0x2000) {
// BG1 layer
int index = dest_addr - 0x1000;
if (index < 1024) {
tiles_bg1_buffer_[index] = tiledata;
total_entries++;
}
} else if (dest_addr < 0x1000) {
// BG2 layer
if (dest_addr < 1024) {
tiles_bg2_buffer_[dest_addr] = tiledata;
total_entries++;
}
}
// Advance destination address
if (increment64) {
dest_addr += 32;
} else {
dest_addr++;
}
// Advance source position
if (!fixsource) {
pos += 2;
}
}
if (fixsource) {
// Read DMA blocks until we hit terminator or safety limit
while (pos < rom->size() && blocks_read < 20) {
// Read destination address (word)
ASSIGN_OR_RETURN(uint16_t dest_addr, rom->ReadWord(pos));
pos += 2;
} else {
pos = posB + ((length / 2) + 1) * 2;
}
// Check for terminator
if (dest_addr == 0xFFFF || (dest_addr & 0xFF) == 0xFF) {
LOG_INFO("TitleScreen", "Found DMA terminator at pos=0x%06X", pos - 2);
break;
}
// Read length/flags (word)
ASSIGN_OR_RETURN(uint16_t length_flags, rom->ReadWord(pos));
pos += 2;
bool increment64 = (length_flags & 0x8000) == 0x8000;
bool fixsource = (length_flags & 0x4000) == 0x4000;
int length = (length_flags & 0x0FFF);
LOG_INFO("TitleScreen", "Block %d: dest=0x%04X, len=%d, inc64=%d, fix=%d",
blocks_read, dest_addr, length, increment64, fixsource);
int tile_count = (length / 2) + 1;
int source_start = pos;
// Read tiles
for (int j = 0; j < tile_count; j++) {
ASSIGN_OR_RETURN(uint16_t tiledata, rom->ReadWord(pos));
// Determine which layer based on destination address
if (dest_addr >= 0x1000 && dest_addr < 0x1400) {
// BG1 layer
int index = (dest_addr - 0x1000) / 2;
if (index < 1024) {
tiles_bg1_buffer_[index] = tiledata;
total_entries++;
}
} else if (dest_addr < 0x0800) {
// BG2 layer
int index = dest_addr / 2;
if (index < 1024) {
tiles_bg2_buffer_[index] = tiledata;
total_entries++;
}
}
// Advance destination address
if (increment64) {
dest_addr += 64;
} else {
dest_addr += 2;
}
// Advance source position
if (!fixsource) {
pos += 2;
}
}
// If fixsource, only advance by one tile
if (fixsource) {
pos = source_start + 2;
}
blocks_read++;
}
LOG_INFO("TitleScreen", "Loaded %d tilemap entries from 7 sections", total_entries);
LOG_INFO("TitleScreen", "Loaded %d tilemap entries from %d DMA blocks (may be incorrect)",
total_entries, blocks_read);
}
pal_selected_ = 2;