Skip to content

Commit

Permalink
patches: load before recompiling the elf entry block
Browse files Browse the repository at this point in the history
Commit 330704a added code which applies the patches before recompiling the
elf entry block, but because at that stage the patches for the current
CRC were not yet loaded, effectively it did nothing.

Now it actually loads the patches before applying them.

As a result, it should now be possible for patches (with place=0) to be
effective before the elf is executed.

This is a hack, because the emulation loads the patches while it's not
paused. It works, but it's not great. A better way would be to pause the
emulation once the entry point is detected, then make the setting get
applied normally (which also loads the patches normally), and then resume
the emulation.

This _should_ properly fix #627 (the test case works as expected now).
  • Loading branch information
avih committed Jul 28, 2016
1 parent defbdcc commit 27e7ecc
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
19 changes: 19 additions & 0 deletions pcsx2/gui/AppCoreThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,10 @@ static void SetupPatchesCon(bool verbose)
// Oh, and updates curGameKey. I think that's it.
// It doesn't require that the emulation is paused, and console writes/title should
// be thread safe, but it's best if things don't move around much while it runs.
static Threading::Mutex mtx__ApplySettings;
static void _ApplySettings( const Pcsx2Config& src, Pcsx2Config& fixup )
{
Threading::ScopedLock lock(mtx__ApplySettings);
// 'fixup' is the EmuConfig we're going to upload to the emulator, which very well may
// differ from the user-configured EmuConfig settings. So we make a copy here and then
// we apply the commandline overrides and database gamefixes, and then upload 'fixup'
Expand Down Expand Up @@ -442,6 +444,23 @@ static void _ApplySettings( const Pcsx2Config& src, Pcsx2Config& fixup )
Console.SetTitle(consoleTitle);
}

// FIXME: This function is not for general consumption. Its only consumer (and
// the only place it's declared at) is i5900-32.cpp .
// It's here specifically to allow loading the patches synchronously (to the caller)
// when the recompiler detects the game's elf entry point, such that the patches
// are applied to the elf in memory before it's getting recompiled.
// TODO: Find a way to pause the recompiler once it detects the elf entry, then
// make AppCoreThread::ApplySettings run more normally, and then resume
// the recompiler.
// The key point is that the patches should be loaded exactly before the elf
// is recompiled. Loading them earlier might incorrectly patch the bios memory,
// and later might be too late since the code was already recompiled
void LoadAllPatchesAndStuff(const Pcsx2Config& cfg)
{
Pcsx2Config dummy;
_ApplySettings(cfg, dummy);
}

void AppCoreThread::ApplySettings( const Pcsx2Config& src )
{
// Re-entry guard protects against cases where code wants to manually set core settings
Expand Down
6 changes: 6 additions & 0 deletions pcsx2/x86/ix86-32/iR5900-32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1562,6 +1562,10 @@ bool skipMPEG_By_Pattern(u32 sPC) {
return 0;
}

// defined at AppCoreThread.cpp but unclean and should not be public. We're the only
// consumers of it, so it's declared only here.
void LoadAllPatchesAndStuff(const Pcsx2Config&);

static void __fastcall recRecompile( const u32 startpc )
{
u32 i = 0;
Expand Down Expand Up @@ -1611,13 +1615,15 @@ static void __fastcall recRecompile( const u32 startpc )

// this is the only way patches get applied, doesn't depend on a hack
if (HWADDR(startpc) == ElfEntry) {
Console.WriteLn(L"Elf entry point @ 0x%08x about to get recompiled. Load patches first.", startpc);

This comment has been minimized.

Copy link
@ssakash

ssakash Jul 29, 2016

Member

DevCon.WriteLn() ? Information is not really useful for the users.

xFastCall(eeGameStarting);
// Apply patch as soon as possible. Normally it is done in
// eeGameStarting but first block is already compiled.
//
// First tentative was to call eeGameStarting directly (not through the
// recompiler) but it crashes some games (GT4, DMC3). It is either a
// thread issue or linked to the various components reset.
LoadAllPatchesAndStuff(EmuConfig);
ApplyLoadedPatches(PPT_ONCE_ON_LOAD);
}

Expand Down

0 comments on commit 27e7ecc

Please sign in to comment.