EndConditionalBlock.cs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. using Ryujinx.HLE.Exceptions;
  2. using Ryujinx.HLE.HOS.Tamper.Conditions;
  3. using Ryujinx.HLE.HOS.Tamper.Operations;
  4. using System.Collections.Generic;
  5. namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters
  6. {
  7. /// <summary>
  8. /// Code type 2 marks the end of a conditional block (started by Code Type 1, Code Type 8 or Code Type C0).
  9. /// </summary>
  10. class EndConditionalBlock
  11. {
  12. public static void Emit(byte[] instruction, CompilationContext context)
  13. {
  14. // 20000000
  15. // Use the conditional begin instruction stored in the stack.
  16. instruction = context.CurrentBlock.BaseInstruction;
  17. CodeType codeType = InstructionHelper.GetCodeType(instruction);
  18. // Pop the current block of operations from the stack so control instructions
  19. // for the conditional can be emitted in the upper block.
  20. IEnumerable<IOperation> operations = context.CurrentOperations;
  21. context.BlockStack.Pop();
  22. ICondition condition;
  23. switch (codeType)
  24. {
  25. case CodeType.BeginMemoryConditionalBlock:
  26. condition = MemoryConditional.Emit(instruction, context);
  27. break;
  28. case CodeType.BeginKeypressConditionalBlock:
  29. condition = KeyPressConditional.Emit(instruction, context);
  30. break;
  31. case CodeType.BeginRegisterConditionalBlock:
  32. condition = RegisterConditional.Emit(instruction, context);
  33. break;
  34. default:
  35. throw new TamperCompilationException($"Conditional end does not match code type {codeType} in Atmosphere cheat");
  36. }
  37. // Create a conditional block with the current operations and nest it in the upper
  38. // block of the stack.
  39. IfBlock block = new IfBlock(condition, operations);
  40. context.CurrentOperations.Add(block);
  41. }
  42. }
  43. }