Skip to content

don't capture memory when read fails#1314

Open
Jamiras wants to merge 4 commits intoRetroAchievements:masterfrom
Jamiras:feature/failed_memory_reads
Open

don't capture memory when read fails#1314
Jamiras wants to merge 4 commits intoRetroAchievements:masterfrom
Jamiras:feature/failed_memory_reads

Conversation

@Jamiras
Copy link
Copy Markdown
Member

@Jamiras Jamiras commented May 5, 2026

Supports https://discord.com/channels/310192285306454017/1359607501213008194/1496647712278319124, which will define very large sparsely populated memory maps.

The "New Search" functionality will ignore any blocks where the emulator returns 0 bytes read, so despite having an 750MB memory map, the captured memory should still only be 256MB - which is still a lot, but a lot less than what it could have been.

Similarly, this will cause "New Search" to not capture empty blocks if a core doesn't expose some part of memory.

@Jamiras Jamiras added this to the 1.4.3 milestone May 5, 2026
@CasualPokePlayer
Copy link
Copy Markdown
Contributor

From my undeerstanding here, this relies on the emulator's RA_ReadMemoryBlockFunc callback to return the number of valid bytes if it ends up reading parts of the memory block that are not actually mapped?

Just noting, that will require some changes in BizHawk's side before this is able to be taken advantage of (not that many anyways, just won't be usable within 2.11.1).

Also on that, how does this code handle validity of the memory blocks changing at runtime? Pages of memory could be unmapped and mapped at runtime, especially say when memory allocation occurs (which might have the game end up mapping more memory as part of increasing one of the heaps, or vice versa with memory deallocation / shrinking the heap). The code doesn't appear to reset m_pInvalid bytes upon successful reads, only setting them upon failed reads.

@Jamiras Jamiras force-pushed the feature/failed_memory_reads branch from 2ecf871 to 5bf2205 Compare May 6, 2026 02:22
@Jamiras
Copy link
Copy Markdown
Member Author

Jamiras commented May 6, 2026

From my undeerstanding here, this relies on the emulator's RA_ReadMemoryBlockFunc callback to return the number of valid bytes if it ends up reading parts of the memory block that are not actually mapped?

Yes. The memory read function (registered via RA_InstallMemoryBankBlockReader or rc_client_set_read_memory_function) returns the number of bytes copied into the buffer. If the return value is 0, this code will now discard that block (previously it would be allocated and just filled with zeroes).

This will happen each time a user starts a "New Search". The entire exposed memory will be "read", but any invalid regions will not actually be captured. If a user filters from that point, only the captured regions will be read, and any of those that return invalid regions will be treated as if the region returned all zeroes.

The code doesn't appear to reset m_pInvalid bytes upon successful reads, only setting them upon failed reads.

m_pInvalid is recalculated each time the current address changes in the memory inspector. It's used to determine which addresses to fill with --s. When the memory is updated each frame, the -- entries will not be updated. But as soon as a user jumps to another address, or scrolls the memory viewer, m_pInvalid will be recalculated at that point as it just corresponds to the active view and not the entire memory map.

I guess it's possible that the user could be viewing a boundary when it gets shifted, but they're more likely to be fixated on a block of memory that's not at the boundary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants