From 4fef9d8d64c49dae52ffb6f5b3c923e67c21c59f Mon Sep 17 00:00:00 2001 From: EmptyChaos Date: Thu, 15 Sep 2016 02:39:11 +0000 Subject: [PATCH] GeckoCode: Don't truncate codes that won't fit The code table builder cuts off the end of codes that won't fit after already writing part of it. That seems quite unlikely to work the way anyone would find useful since the codes can contain actual PPC instructions. --- Source/Core/Core/GeckoCode.cpp | 38 +++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/Source/Core/Core/GeckoCode.cpp b/Source/Core/Core/GeckoCode.cpp index 2845e9d778..9ad15b94f6 100644 --- a/Source/Core/Core/GeckoCode.cpp +++ b/Source/Core/Core/GeckoCode.cpp @@ -108,28 +108,38 @@ static bool InstallCodeHandlerLocked() PowerPC::HostWrite_U32(0x00d0c0de, codelist_base_address); PowerPC::HostWrite_U32(0x00d0c0de, codelist_base_address + 4); - int i = 0; + // Each code is 8 bytes (2 words) wide. There is a starter code and an end code. + const u32 start_address = codelist_base_address + CODE_SIZE; + const u32 end_address = codelist_end_address - CODE_SIZE; + u32 next_address = start_address; + // NOTE: Only active codes are in the list for (const GeckoCode& active_code : s_active_codes) { - if (active_code.enabled) + // If the code is not going to fit in the space we have left then we have to skip it + if (next_address + active_code.codes.size() * CODE_SIZE > end_address) { - for (const GeckoCode::Code& code : active_code.codes) - { - // Make sure we have enough memory to hold the code list - if ((codelist_base_address + CODE_SIZE * 3 + i) < codelist_end_address) - { - PowerPC::HostWrite_U32(code.address, codelist_base_address + CODE_SIZE + i); - PowerPC::HostWrite_U32(code.data, codelist_base_address + CODE_SIZE + 4 + i); - i += CODE_SIZE; - } - } + NOTICE_LOG(ACTIONREPLAY, "Too many GeckoCodes! Ran out of storage space in Game RAM. Could " + "not write: \"%s\". Need %zu bytes, only %u remain.", + active_code.name.c_str(), active_code.codes.size() * CODE_SIZE, + end_address - next_address); + continue; + } + + for (const GeckoCode::Code& code : active_code.codes) + { + PowerPC::HostWrite_U32(code.address, next_address); + PowerPC::HostWrite_U32(code.data, next_address + 4); + next_address += CODE_SIZE; } } + WARN_LOG(ACTIONREPLAY, "GeckoCodes: Using %u of %u bytes", next_address - start_address, + end_address - start_address); + // Stop code. Tells the handler that this is the end of the list. - PowerPC::HostWrite_U32(0xF0000000, codelist_base_address + CODE_SIZE + i); - PowerPC::HostWrite_U32(0x00000000, codelist_base_address + CODE_SIZE + 4 + i); + PowerPC::HostWrite_U32(0xF0000000, next_address); + PowerPC::HostWrite_U32(0x00000000, next_address + 4); // Turn on codes PowerPC::HostWrite_U8(1, INSTALLER_BASE_ADDRESS + 7);