using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.HOS.Tamper.Conditions; using Ryujinx.HLE.HOS.Tamper.Operations; using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters { /// /// Code type 2 marks the end of a conditional block (started by Code Type 1, Code Type 8 or Code Type C0). /// class EndConditionalBlock { public static void Emit(byte[] instruction, CompilationContext context) { // 20000000 // Use the conditional begin instruction stored in the stack. instruction = context.CurrentBlock.BaseInstruction; CodeType codeType = InstructionHelper.GetCodeType(instruction); // Pop the current block of operations from the stack so control instructions // for the conditional can be emitted in the upper block. IEnumerable operations = context.CurrentOperations; context.BlockStack.Pop(); ICondition condition; switch (codeType) { case CodeType.BeginMemoryConditionalBlock: condition = MemoryConditional.Emit(instruction, context); break; case CodeType.BeginKeypressConditionalBlock: condition = KeyPressConditional.Emit(instruction, context); break; case CodeType.BeginRegisterConditionalBlock: condition = RegisterConditional.Emit(instruction, context); break; default: throw new TamperCompilationException($"Conditional end does not match code type {codeType} in Atmosphere cheat"); } // Create a conditional block with the current operations and nest it in the upper // block of the stack. IfBlock block = new IfBlock(condition, operations); context.CurrentOperations.Add(block); } } }