-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PatchEngine: Allow patching of files on disk #7982
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We talked a little on IRC about having this code in the Volume classes instead. I think that would make sense, as long as we make sure that the patches only are applied when the disc is being accessed by emulation and not the game list, maybe by having a function Volume::ApplyPatches
that is called by the boot code or PatchEngine that stores the patches in the Volume object.
Source/Core/Core/PatchEngine.cpp
Outdated
const auto& file = fs->FindFileInfo(patch.path); | ||
if (file) { | ||
for (const auto& entry : patch.entries) { | ||
u64 disc_offset = disc.PartitionOffsetToRawOffset(file->GetOffset(), partition) + entry.address; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wrong for Wii discs, since entry.address doesn't account for the hashes at the beginning of each cluster. (Unless you expect the person writing the patch to correct for the hashes manually?) Patching a Wii disc using the current code is inconvenient anyway, since you would need to handle the encryption manually...
If the code isn't going to support Wii discs properly, you might as well skip the call to PartitionOffsetToRawOffset
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Disregard the previous comment. You can get Wii discs to work, but you would need to remove this call to PartitionOffsetToRawOffset
, and PatchReadRequest
would need to check which partition it's applying patches to.
@@ -386,15 +386,15 @@ static void PatchReadRequest(std::vector<u8>& buffer, u64 offset) | |||
u64 start = it->first - offset; | |||
std::memmove(buffer.data() + start, it->second.data(), | |||
std::min(it->second.size(), buffer.size() - start)); | |||
INFO_LOG(DVDINTERFACE, "patch applied at %08lx", offset + start); | |||
INFO_LOG(DVDINTERFACE, "patch applied at %08llux", offset + start); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should use PRIx64
for u64
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
Current versions of Visual studio support %llux
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
%llu
works for u64
without warnings on all compilers now? I guess you could use that then.
DVDInterface::SetDisc(std::move(volume), auto_disc_change_paths); | ||
return pointer; | ||
return DVDThread::GetDiscVolume(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a really ugly situation here. It might actually be cleaner to return to the state before PR #4241
Right now I'm just making it clearer that we are grabbing a pointer internal state of DVDThread (and grabbing it after DVDThread has applyed the patch overlay).
I think the cleaner solution might be to split the EmulatedBS2 into two parts. Part one which sets up the memory/state based on the volume which runs before passing the volume to DVDThread. Part 2 will just load and run apploader, directly calling DVDThread to process read requests (adding a new DVDThread::HLE_Read()
which is only intended to be used during boot)
But I'm not sure, I welcome feedback on this issue.
Since this is stalled, do you mind if i create a romhacking.net patch for the discs using xdelta using your offsets? And is this for both games or just one? And the offset is inside the files, not the whole disc or partition right? |
Just RE2... |
Coincidentally, I'm rebasing this PR right now. Those offsets work only for the US version of RE2. Offset is within the file. |
If it's happening i'll wait since this only emulator for the gamecube worth a damn. I'd prefer to do/get/replay both at once anyway. |
We also switch from keeping two lists in sync to a system with a single list.
Do you happen to have already researched the offsets for Resident Evil 3 too? |
I would like to go with PR #9308 instead of this PR. Since it seems like that PR's approach works for fixing RE2/3, this PR's more complicated solution seems like overkill for just fixing those two games. And I don't feel like this PR is useful for a lot more than fixing RE2/3, as large-scale game patching (like adding new levels to a game) requires features that can't be provided by this PR's approach, like changing the size of files. |
The |
like changing the size of files.
The plan was that the backend disc patching architecture here is generic.
It simply takes lists of modified ranges in disc address space.
A later PR could add an improved frontend that would understand more
advanced patch types (such as deleting files, adding new files, replacing
files with bigger versions, rearranging the filesystem, maybe even creating
oversized discs) in more specialized formats and generate the "list of
modified ranges" for the disc patching backend to consume.
…On Wed, 16 Dec 2020, 3:32 AM JosJuice, ***@***.***> wrote:
The Unifiy AR/Gecko/Patch GUI dialogs commit seems like a good idea
regardless, though. If you can split it out to a separate PR, I'd like to
try to get it merged.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#7982 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABBZ5C3ZX53YNEJ5HLXZ4LSU5XN7ANCNFSM4HFFY4EQ>
.
|
I don't think this is an either-or situation. The RE 2&3 patches will function identically no matter which application mechanism is used. They can be trivially converted to use either. That said, I would still like to go ahead with my change. It's just a dozen lines of code in the patch engine; the bulk of the source changes are in the Qt UI, and that code will be thrown away entirely if this PR is completed, which wouldn't bother me in the slightest. |
Yeah, it will function near identically. I chose this option because:
Conditional patches are also useful in their own way. Ideally dolphin wants both. |
Agreed on all points. |
Wouldn't this make the list of modified ranges absolutely huge once you start moving files around on the disc? |
Really depends on how easy it is to extend the disc beyond 1.2GB (something I haven't looked into). If the Nintendo SDK library routines simply fall apart, then we will be forced to pack everything into 1.2GB, deleting and packing files down. A HLE approach might be preferable. If it's easy to extend discs, then it's super simple. |
I'd like to close this now that we have PR #10127. Any objections? |
Resident Evil 2/3 require patching code which live in .rel files (Relocatable Executable)
Our current memory patching system makes this difficult, we would have to patch the rel loader to detect which .rel was loaded and apply the correct patch.
So I've implemented file based patches instead.
Here is the patch for Resident Evil 2 (U)
Current limitations: