fix: back up the hotswap slot

The game checks if the slot being switched to is already selected and
does nothing if so. (For what it's worth, I did try changing the code
in memory to ignore these checks, but it didn't seem to work.) In
order to get the game to change slot, we write a different slot number
to the "current" slot in memory and then ask the game to change slot.

This doesn't swap the slot on screen and still works, which is
ideal. However, the game seems to overwrite the slot that is marked as
current when we do this. To remedy this issue, back up the slot before
telling the game to swap, then restore the slot afterwards.
This commit is contained in:
Anna 2020-07-30 13:21:08 -04:00
parent d2d352b435
commit d1b122576d
1 changed files with 19 additions and 5 deletions

View File

@ -32,15 +32,29 @@ namespace HudSwap {
public uint SelectSlot(HudSlot slot, bool force = false) {
IntPtr file = this.GetFilePointer(0);
// change the current slot so the game lets us pick one that's currently in use
if (force) {
IntPtr currentSlotPtr = this.GetDataPointer() + 0x5958;
// read the current slot
uint currentSlot = (uint)Marshal.ReadInt32(currentSlotPtr);
if (currentSlot < 3) {
currentSlot += 1;
} else {
currentSlot = 0;
// change it to a different slot
if (currentSlot == (uint)slot) {
if (currentSlot < 3) {
currentSlot += 1;
} else {
currentSlot = 0;
}
// back up this different slot
byte[] backup = this.ReadLayout((HudSlot)currentSlot);
// change the current slot in memory
Marshal.WriteInt32(currentSlotPtr, (int)currentSlot);
// ask the game to change slot to our desired slot
// for some reason, this overwrites the current slot, so this is why we back up
uint res = this._setHudLayout.Invoke(file, (uint)slot, 0, 1);
// restore the backup
this.WriteLayout((HudSlot)currentSlot, backup);
return res;
}
Marshal.WriteInt32(currentSlotPtr, (int)currentSlot);
}
return this._setHudLayout.Invoke(file, (uint)slot, 0, 1);
}