diff --git a/docs/features/cheats.md b/docs/features/cheats.md index 6412bf14e..bf7320f23 100644 --- a/docs/features/cheats.md +++ b/docs/features/cheats.md @@ -49,7 +49,7 @@ Code type 0x0 allows writing a static value to a memory address. `0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` + T: Width of memory write (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = none). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). + R: Register to use as an offset from memory region base. + A: Immediate offset to use from memory region base. + V: Value to write. @@ -65,7 +65,7 @@ If the condition is not met, all instructions until the appropriate End or Else `1TMCXrAA AAAAAAAA VVVVVVVV (VVVVVVVV)` + T: Width of memory read (1, 2, 4, or 8 bytes). -+ M: Memory region to read from (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = none). ++ M: Memory region to read from (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). + C: Condition to use, see below. + X: Operand Type, see below. + r: Offset Register (operand types 1). @@ -131,7 +131,7 @@ Code type 0x5 allows loading a value from memory into a register, either using a `5TMR00AA AAAAAAAA` + T: Width of memory read (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = none). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). + R: Register to load value into. + A: Immediate offset to use from memory region base. @@ -154,7 +154,7 @@ Code type 0x5 allows loading a value from memory into a register, either using a `5TMR3SAA AAAAAAAA` + T: Width of memory read (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = none). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative). + R: Register to load value into. + S: Register to use as offset register. + A: Immediate offset to use from memory region base. @@ -408,7 +408,7 @@ Code type 0xC3 reads or writes a static register with a given register. Code type 0xC4 enters or skips a conditional block based on whether a key combination is pressed. #### Encoding -`C4r000kk kkkkkkkk` +`C4r00000 kkkkkkkk kkkkkkkk` + r: Auto-repeat, see below. + kkkkkkkkkk: Keypad mask to check against output of `hidKeysDown()`. diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp index 70b14fe8d..c1ecfb675 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp @@ -473,9 +473,9 @@ namespace ams::dmnt::cheat::impl { break; case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: { - /* C4r000kk kkkkkkkk */ + /* C4r00000 kkkkkkkk kkkkkkkk */ /* Read additional words. */ - opcode.begin_ext_keypress_cond.key_mask = (((u64)first_dword & 0xFF) << 32ul) | ((u64)GetNextDword()); + opcode.begin_ext_keypress_cond.key_mask = (u64)GetNextDword() << 32ul | (u64)GetNextDword(); opcode.begin_ext_keypress_cond.auto_repeat = ((first_dword >> 20) & 0xF) != 0; } break; @@ -753,7 +753,7 @@ namespace ams::dmnt::cheat::impl { return metadata->alias_extents.base + rel_address; case MemoryAccessType_Aslr: return metadata->aslr_extents.base + rel_address; - case MemoryAccessType_Blank: + case MemoryAccessType_NonRelative: return rel_address; } } @@ -790,7 +790,7 @@ namespace ams::dmnt::cheat::impl { return true; } - static u64 keyold = 0; + static u64 s_keyold = 0; void CheatVirtualMachine::Execute(const CheatProcessMetadata *metadata) { CheatVmOpcode cur_opcode; u64 kHeld = 0; @@ -1011,7 +1011,7 @@ namespace ams::dmnt::cheat::impl { case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: /* Check for keypress. */ if (!cur_opcode.begin_ext_keypress_cond.auto_repeat) { - if ((cur_opcode.begin_ext_keypress_cond.key_mask & kHeld) != (cur_opcode.begin_ext_keypress_cond.key_mask) || (cur_opcode.begin_ext_keypress_cond.key_mask & keyold) == (cur_opcode.begin_ext_keypress_cond.key_mask)) { + if ((cur_opcode.begin_ext_keypress_cond.key_mask & kHeld) != (cur_opcode.begin_ext_keypress_cond.key_mask) || (cur_opcode.begin_ext_keypress_cond.key_mask & s_keyold) == (cur_opcode.begin_ext_keypress_cond.key_mask)) { /* Keys not pressed. Skip conditional block. */ this->SkipConditionalBlock(true); } @@ -1061,29 +1061,33 @@ namespace ams::dmnt::cheat::impl { res_val = operand_1_value; break; case RegisterArithmeticType_FloatAddition: - if (cur_opcode.perform_math_reg.bit_width == 4) - *(float *)&res_val = *(float *)&operand_1_value + *(float *)&operand_2_value; - if (cur_opcode.perform_math_reg.bit_width == 8) - *(double *)&res_val = *(double *)&operand_1_value + *(double *)&operand_2_value; + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) + std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) + std::bit_cast(operand_2_value)); + } + break; + case RegisterArithmeticType_FloatSubtraction: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) - std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) - std::bit_cast(operand_2_value)); + } + break; + case RegisterArithmeticType_FloatMultiplication: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) * std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) * std::bit_cast(operand_2_value)); + } + break; + case RegisterArithmeticType_FloatDivision: + if (cur_opcode.perform_math_reg.bit_width == 4) { + res_val = std::bit_cast(std::bit_cast(static_cast(operand_1_value)) / std::bit_cast(static_cast(operand_2_value))); + } else if (cur_opcode.perform_math_reg.bit_width == 8) { + res_val = std::bit_cast(std::bit_cast(operand_1_value) / std::bit_cast(operand_2_value)); + } break; - case RegisterArithmeticType_FloatSubtraction: { - if (cur_opcode.perform_math_reg.bit_width == 4) - *(float *)&res_val = *(float *)&operand_1_value - *(float *)&operand_2_value; - if (cur_opcode.perform_math_reg.bit_width == 8) - *(double *)&res_val = *(double *)&operand_1_value - *(double *)&operand_2_value; - } break; - case RegisterArithmeticType_FloatMultiplication: { - if (cur_opcode.perform_math_reg.bit_width == 4) - *(float *)&res_val = *(float *)&operand_1_value * *(float *)&operand_2_value; - if (cur_opcode.perform_math_reg.bit_width == 8) - *(double *)&res_val = *(double *)&operand_1_value * *(double *)&operand_2_value; - } break; - case RegisterArithmeticType_FloatDivision: { - if (cur_opcode.perform_math_reg.bit_width == 4) - *(float *)&res_val = *(float *)&operand_1_value / *(float *)&operand_2_value; - if (cur_opcode.perform_math_reg.bit_width == 8) - *(double *)&res_val = *(double *)&operand_1_value / *(double *)&operand_2_value; - } break; } @@ -1366,7 +1370,7 @@ namespace ams::dmnt::cheat::impl { break; } } - keyold = kHeld; + s_keyold = kHeld; } } diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp index 573d7796d..2dd958d5c 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp @@ -60,7 +60,7 @@ namespace ams::dmnt::cheat::impl { MemoryAccessType_Heap = 1, MemoryAccessType_Alias = 2, MemoryAccessType_Aslr = 3, - MemoryAccessType_Blank = 4, + MemoryAccessType_NonRelative = 4, }; enum ConditionalComparisonType : u32 {