Patches/No Checksum
Milo engine games, starting with Rock Band 1, validate the checksum of important files, usually just DTA and MIDI files, within the ARK using the StreamChecksum::ValidateChecksum
function. If the checksum mismatches, the result is usually the entire game shutting down with a "dirty disc" error.
It's possible to patch this behaviour out, by either disabling StreamChecksum from validating or disabling the disk error functionality. This page should guide you through this process, assuming you have the executable for the game loaded into Ghidra or IDA and you know the basics of navigating around them.
Xbox 360
This patch will disable the PlatformMgr::SetDiskError
as that is the easiest function to locate and patch when starting from zero, and has very little change between engine revisions.
PlatformMgr::SetDiskError
can be found by doing a memory search for 2f 0b 00 03 41 9a 00 ?? 7f 0b 20 00 41 9a 00 ??
- locating the start of this function, a "mfspr r12, LR" (7d 88 02 a6
), and replacing it with a "blr" (4e 80 00 20
), will disable checksum validation errors by preventing the game from setting the mDiskError value in PlatformMgr and from calling XamShowDirtyDiscErrorUI.
That memory signature will match the first line of SetDiskError, which is if ((this->mDiscError != kFailedChecksum) && (this->mDiscError != error_code)) {
Alternatively, if that function signature does not work, you can use the XamShowDirtyDiscErrorUI import as a spring board to find PlatformMgr::SetDiskError. By locating the import and jumping to the first cross-reference / XRef of that function, you should ese a function that looks like the following in the Decompiler view.
void XShowDirtyDiscErrorUI(uint r3) { // will appear as FUN_82xxxxxx XamShowDirtyDiscErrorUI(r3); XLaunchNewImage(0,0); // will appear as FUN_82xxxxxx }
You can check this function's singular XRef to find the thunk function responsible for setting r3 and calling it. It should look like the following in the Disassembler view:
ShowDirtyDiscError // will appear as FUN_82xxxxxx 38 60 00 00 li r3,0x0 48 51 ef 0c b XShowDirtyDiscErrorUI // the function from early, should be the same FUN address
Scrolling up in the disassembler view, or clicking the second XRef, should get you a function that gets a pointer and dereferences it - that pointer should lead to the above function. Example:
void * GetDiscErrorFunction(void) { // will appear as FUN_82xxxxxx return PTR_ShowDirtyDiscError_82xxxxxx; }
The one XRef to this function will be from SetDiskError - you will know if the first line in the Decompiler view looks similar to if ((*(int *)(this + 0x28) != 3) && (*(int *)(this + 0x28) != param_1))
. Replace the first / "mfspr" instruction of this function with "blr" and you will have checksums patched!
When using debug builds that have debug printing enabled, you can also search for the string DISK ERROR\n
, which will only have 1 XRef within the SetDiskError function. Please keep in mind that
Guide by Emma / InvoxiPlayGames.
Other platforms
TBA - PS3 cares, Wii doesn't seem to, unsure about PC/iPod/etc