Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'ES_LAUNCH'
Games that are now playable:

Back to the Future: The Game
CSI - Hard Evidence
CSI - Deadly Intent
CSI - Fatal Conspiracy
Red Steel
Metroid Prime: Trilogy
Wii Sports + Wii Sports Resort pack
Sam & Max: Season One
Sam & Max: Beyond Time and Space
Kirby's Dream Collection: Classic Collection
Indiana Jones and the Staff of Kings: Fate of Atlantis


* ES_LAUNCH:
  Fixed SSBB from starting at the mini-games screen.
  Build fix
  Corrected a state bug where newly loaded dols did not have their patches applied.
  Changed the HLE system to allow it to hook the beginning, the end or replace the entire function without changing the GC memory.  Fixes Kirby's Return to Dreamland. Added a way to categorise the type of HLE function.  Currently, there are debug, floating point, memory and generic functions. Added a HLE function for OSGetResetCode (Warm reset).  Fixes the CSI games. Added a switch to disable all of the HLE functions if the idle skipping option is disabled.
  Added some IOS version checks and code to clear memory before loading the dol.
  Added support for Reset (from menu).  Fixes Sam & Max.
  Added an IOS check as games which use IOS older than IOS30 do not need to be HLE'd.  Added some stubs for Reset to Menu and SSBB's load from disc partition.  Fixed loading Fate of Atlantis from the Indiana Jones and the Staff of Kings game.
  Added argument detection and passing to the loaded dol.  This fixes the Wii Sports+Wii Sports Resort bundle pack.
  Added preliminary support for ES_LAUNCH (Wii Multi-boot games) by using HLE to hijack the OSBootDol function.

Conflicts:
	Source/Core/DiscIO/Src/FileSystemGCWii.cpp
  • Loading branch information
skidau committed Jan 16, 2013
2 parents 54974cb + 1d691d7 commit 7e5d877
Show file tree
Hide file tree
Showing 18 changed files with 576 additions and 112 deletions.
Binary file modified Data/Sys/totaldb.dsy
Binary file not shown.
13 changes: 13 additions & 0 deletions Source/Core/Core/Src/Boot/Boot.cpp
Expand Up @@ -257,6 +257,19 @@ bool CBoot::BootUp()
EmulatedBS2(_StartupPara.bWii);
}

// Scan for common HLE functions
if (_StartupPara.bSkipIdle && !_StartupPara.bEnableDebugging)
{
PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB);
SignatureDB db;
if (db.Load((File::GetSysDirectory() + TOTALDB).c_str()))
{
db.Apply(&g_symbolDB);
HLE::PatchFunctions();
db.Clear();
}
}

/* Try to load the symbol map if there is one, and then scan it for
and eventually replace code */
if (LoadMapFromFilename(_StartupPara.m_strFilename, gameID))
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/Src/Boot/Boot_BS2Emu.cpp
Expand Up @@ -375,7 +375,7 @@ bool CBoot::EmulatedBS2_Wii()
u32 iLength = Memory::ReadUnchecked_U32(0x81300008);
u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c) << 2;

INFO_LOG(BOOT, "DVDRead: offset: %08x memOffse: %08x length: %i", iDVDOffset, iRamAddress, iLength);
INFO_LOG(BOOT, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset, iRamAddress, iLength);
DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength);
} while(PowerPC::ppcState.gpr[3] != 0x00);

Expand Down
142 changes: 97 additions & 45 deletions Source/Core/Core/Src/HLE/HLE.cpp
Expand Up @@ -15,7 +15,6 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/

#include <map>
#include "Common.h"

#include "HLE.h"
Expand All @@ -27,6 +26,9 @@

#include "HLE_OS.h"
#include "HLE_Misc.h"
#include "IPC_HLE/WII_IPC_HLE_Device_es.h"
#include "ConfigManager.h"
#include "Core.h"

namespace HLE
{
Expand All @@ -45,73 +47,86 @@ struct SPatch
{
char m_szPatchName[128];
TPatchFunction PatchFunction;
int type;
int flags;
};

static const SPatch OSPatches[] =
{
{ "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction },
{ "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },

// speedup
//{ "OSProtectRange", HLE_Misc::UnimplementedFunctionFalse },
//{ "THPPlayerGetState", HLE_Misc:THPPlayerGetState },
//{ "OSProtectRange", HLE_Misc::UnimplementedFunctionFalse, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ "THPPlayerGetState", HLE_Misc:THPPlayerGetState, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ "memcpy", HLE_Misc::gc_memcpy, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY },
//{ "memcmp", HLE_Misc::gc_memcmp, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY },
//{ "memset", HLE_Misc::gc_memset, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY },
//{ "memmove", HLE_Misc::gc_memmove, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY },

//{ "__div2i", HLE_Misc::div2i, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // Slower?
//{ "__div2u", HLE_Misc::div2u, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // Slower?

//{ "DCFlushRange", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ "DCInvalidateRange", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ "DCZeroRange", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },

// debug out is very nice ;)
{ "OSReport", HLE_OS::HLE_GeneralDebugPrint },
{ "DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint },
{ "WUD_DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint },
{ "OSPanic", HLE_OS::HLE_OSPanic },
{ "vprintf", HLE_OS::HLE_GeneralDebugPrint },
{ "printf", HLE_OS::HLE_GeneralDebugPrint },
{ "puts", HLE_OS::HLE_GeneralDebugPrint }, // gcc-optimized printf?
{ "___blank(char *,...)", HLE_OS::HLE_GeneralDebugPrint }, // used for early init things (normally)
{ "___blank", HLE_OS::HLE_GeneralDebugPrint },
{ "__write_console", HLE_OS::HLE_write_console }, // used by sysmenu (+more?)
{ "OSReport", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
{ "DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
{ "WUD_DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
{ "OSPanic", HLE_OS::HLE_OSPanic, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
{ "vprintf", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
{ "printf", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
{ "puts", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // gcc-optimized printf?
{ "___blank(char *,...)", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // used for early init things (normally)
{ "___blank", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
{ "__write_console", HLE_OS::HLE_write_console, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // used by sysmenu (+more?)

// wii only
//{ "__OSInitAudioSystem", HLE_Misc::UnimplementedFunction },
//{ "__OSInitAudioSystem", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },

// Super Monkey Ball - no longer needed.
//{ ".evil_vec_cosine", HLE_Misc::SMB_EvilVecCosine },
//{ ".evil_normalize", HLE_Misc::SMB_EvilNormalize },
//{ ".evil_vec_setlength", HLE_Misc::SMB_evil_vec_setlength },
//{ ".evil_vec_something", HLE_Misc::FZero_evil_vec_normalize },
{ "PanicAlert", HLE_Misc::HLEPanicAlert },
//{ ".sqrt_internal_needs_cr1", HLE_Misc::SMB_sqrt_internal },
//{ ".rsqrt_internal_needs_cr1", HLE_Misc::SMB_rsqrt_internal },
//{ ".atan2", HLE_Misc::SMB_atan2},
//{ ".sqrt_fz", HLE_Misc::FZ_sqrt},
//{ ".evil_vec_cosine", HLE_Misc::SMB_EvilVecCosine, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ ".evil_normalize", HLE_Misc::SMB_EvilNormalize, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ ".evil_vec_setlength", HLE_Misc::SMB_evil_vec_setlength, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ ".evil_vec_something", HLE_Misc::FZero_evil_vec_normalize, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
{ "PanicAlert", HLE_Misc::HLEPanicAlert, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
//{ ".sqrt_internal_needs_cr1", HLE_Misc::SMB_sqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ ".rsqrt_internal_needs_cr1", HLE_Misc::SMB_rsqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ ".atan2", HLE_Misc::SMB_atan2HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ ".sqrt_fz", HLE_Misc::FZ_sqrtHLE_HOOK_REPLACE, HLE_TYPE_GENERIC },

// F-zero still isn't working correctly, but these aren't really helping.

//{ ".sqrt_internal_fz", HLE_Misc::FZ_sqrt_internal },
//{ ".rsqrt_internal_fz", HLE_Misc::FZ_rsqrt_internal },
//{ ".sqrt_internal_fz", HLE_Misc::FZ_sqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
//{ ".rsqrt_internal_fz", HLE_Misc::FZ_rsqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },

//{ ".kill_infinites", HLE_Misc::FZero_kill_infinites },
//{ ".kill_infinites", HLE_Misc::FZero_kill_infinites, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
// special
// { "GXPeekZ", HLE_Misc::GXPeekZ},
// { "GXPeekARGB", HLE_Misc::GXPeekARGB},
// { "GXPeekZ", HLE_Misc::GXPeekZHLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
// { "GXPeekARGB", HLE_Misc::GXPeekARGBHLE_HOOK_REPLACE, HLE_TYPE_GENERIC },

// Name doesn't matter, installed in CBoot::BootUp()
{ "HBReload", HLE_Misc::HBReload },
{ "HBReload", HLE_Misc::HBReload, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },

// ES_LAUNCH
{ "__OSBootDol", HLE_Misc::OSBootDol, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
{ "OSGetResetCode", HLE_Misc::OSGetResetCode, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },

};

static const SPatch OSBreakPoints[] =
{
{ "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction },
};


static std::map<u32, u32> orig_instruction;

void Patch(u32 address, const char *hle_func_name)
void Patch(u32 addr, const char *hle_func_name)
{
for (u32 i = 0; i < sizeof(OSPatches) / sizeof(SPatch); i++)
{
if (!strcmp(OSPatches[i].m_szPatchName, hle_func_name))
{
u32 HLEPatchValue = (1 & 0x3f) << 26;
Memory::Write_U32(HLEPatchValue | i, address);
orig_instruction[addr] = i;
return;
}
}
Expand All @@ -125,23 +140,24 @@ void PatchFunctions()
Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName);
if (symbol > 0)
{
u32 HLEPatchValue = (1 & 0x3f) << 26;
for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4)
{
orig_instruction[addr] = Memory::ReadUnchecked_U32(addr);
Memory::Write_U32(HLEPatchValue | i, addr);
orig_instruction[addr] = i;
}
INFO_LOG(OSHLE, "Patching %s %08x", OSPatches[i].m_szPatchName, symbol->address);
}
}

for (size_t i = 1; i < sizeof(OSBreakPoints) / sizeof(SPatch); i++)
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
{
Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName);
if (symbol > 0)
for (size_t i = 1; i < sizeof(OSBreakPoints) / sizeof(SPatch); i++)
{
PowerPC::breakpoints.Add(symbol->address, false);
INFO_LOG(OSHLE, "Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol->address);
Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName);
if (symbol > 0)
{
PowerPC::breakpoints.Add(symbol->address, false);
INFO_LOG(OSHLE, "Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol->address);
}
}
}

Expand All @@ -163,10 +179,46 @@ void Execute(u32 _CurrentPC, u32 _Instruction)
// _dbg_assert_msg_(HLE,NPC == LR, "Broken HLE function (doesn't set NPC)", OSPatches[pos].m_szPatchName);
}

u32 GetOrigInstruction(u32 addr)
u32 GetFunctionIndex(u32 addr)
{
std::map<u32, u32>::const_iterator iter = orig_instruction.find(addr);
return (iter != orig_instruction.end()) ? iter->second : 0;
}

int GetFunctionTypeByIndex(u32 index)
{
return OSPatches[index].type;
}

int GetFunctionFlagsByIndex(u32 index)
{
return OSPatches[index].flags;
}

bool IsEnabled(int flags)
{
if (flags == HLE::HLE_TYPE_MEMORY && Core::g_CoreStartupParameter.bMMU)
return false;

if (flags == HLE::HLE_TYPE_DEBUG && !Core::g_CoreStartupParameter.bEnableDebugging && PowerPC::GetMode() != MODE_INTERPRETER)
return false;

return true;
}

u32 UnPatch(std::string patchName)
{
Symbol *symbol = g_symbolDB.GetSymbolFromName(patchName.c_str());
if (symbol > 0)
{
for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4)
{
orig_instruction[addr] = 0;
PowerPC::ppcState.iCache.Invalidate(addr);
}
return symbol->address;
}
return 0;
}

} // end of namespace HLE
27 changes: 26 additions & 1 deletion Source/Core/Core/Src/HLE/HLE.h
Expand Up @@ -18,15 +18,40 @@
#ifndef _HLE_H
#define _HLE_H

#include <map>
#include "Common.h"

namespace HLE
{
enum
{
HLE_HOOK_START = 0, // Hook the beginning of the function and execute the function afterwards
HLE_HOOK_END = 1, // Hook the end of the function, executing the function first before the hook
HLE_HOOK_REPLACE = 2, // Replace the function with the HLE version
HLE_HOOK_NONE = 3, // Do not hook the function
};

enum
{
HLE_TYPE_GENERIC = 0, // Miscellaneous function
HLE_TYPE_MEMORY = 1, // Memory operation
HLE_TYPE_FP = 2, // Floating Point operation
HLE_TYPE_DEBUG = 3, // Debug output function
};

void PatchFunctions();

void Patch(u32 pc, const char *func_name);
u32 UnPatch(std::string patchName);
void Execute(u32 _CurrentPC, u32 _Instruction);

u32 GetOrigInstruction(u32 em_address);
u32 GetFunctionIndex(u32 em_address);
int GetFunctionTypeByIndex(u32 index);
int GetFunctionFlagsByIndex(u32 index);

bool IsEnabled(int flags);

static std::map<u32, u32> orig_instruction;
}

#endif
Expand Down

0 comments on commit 7e5d877

Please sign in to comment.