Skip to content

Commit

Permalink
Fix #30, improve Powercam (Auto-Powercam), alpha 6
Browse files Browse the repository at this point in the history
  • Loading branch information
GlitchyPSIX committed May 18, 2021
1 parent 6b83c2e commit e36906a
Show file tree
Hide file tree
Showing 12 changed files with 563 additions and 405 deletions.
4 changes: 2 additions & 2 deletions M64MM.Utils/CameraStyle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace M64MM.Utils

public struct CameraStyle
{
public byte Value;
public string Name;
public byte Value { get; set; }
public string Name { get; set; }
}
}
69 changes: 57 additions & 12 deletions M64MM.Utils/Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,20 @@ public static class Core
public static List<ColorCodeGS> colorCodeGamesharks = new List<ColorCodeGS>();
public static Animation defaultAnimation;
public static byte[] emptyWord = new byte[] { 0, 0, 0, 0 };
public static readonly int[] levelsZ_O = new int[] { 5, 8, 9, 10, 11, 13, 15, 16, 17, 19, 21, 22, 24, 29, 30, 31, 33, 34, 36 };
public static SettingsGroup coreSettingsGroup;
static bool _cameraFrozen = false;
static bool _cameraSoftFrozen = false;

public enum PowerCameraStyleStage
{
UNSET,
CLEAN,
DIRTY
}

public static PowerCameraStyleStage PowerCamStyleStage { get; set; } = PowerCameraStyleStage.UNSET;

public static bool PowerCamEnabled { get; set; }

public static bool CameraFrozen
Expand Down Expand Up @@ -63,6 +73,8 @@ public static bool CameraSoftFrozen
// Settings related variables
public static bool enableHotkeys;
public static bool enableUpdates;
public static byte preferredCameraStyle = 0x01;
public static bool prePowercam = true;

// Timers
public static Timer programTimer = new Timer();
Expand Down Expand Up @@ -96,6 +108,15 @@ public static byte[] CameraState
private set { }
}

public static byte[] CameraStyle
{
get
{
return ReadBytes(BaseAddress + 0x33C6D6, 2);
}
private set { }
}

// Animation Index
public static short AnimationIndex
{
Expand Down Expand Up @@ -228,6 +249,8 @@ public static async void InitSettings()
coreSettingsGroup = GetSettingsGroup("core", true);
coreSettingsGroup.SetSettingValue("enableHotkeys", true);
coreSettingsGroup.SetSettingValue("enableUpdateCheck", true);
coreSettingsGroup.SetSettingValue("enableStartupPowercam", true);
coreSettingsGroup.SetSettingValue<byte>("preferredDefaultCamStyle", 0x01);
UpdateLocalVariables();
using (StreamWriter rw = new StreamWriter($"{Application.StartupPath}/config.json"))
{
Expand Down Expand Up @@ -255,6 +278,8 @@ static void UpdateLocalVariables()
{
enableHotkeys = coreSettingsGroup.EnsureSettingValue<bool>("enableHotkeys");
enableUpdates = coreSettingsGroup.EnsureSettingValue<bool>("enableUpdateCheck");
prePowercam = coreSettingsGroup.EnsureSettingValue<bool>("enableStartupPowercam");
preferredCameraStyle = coreSettingsGroup.EnsureSettingValue<byte>("preferredDefaultCamStyle");
}

#endregion
Expand Down Expand Up @@ -381,6 +406,11 @@ public static void ToggleCameraSoftFreeze()

}

public static bool WillLevelZoomOut(int id)
{
return levelsZ_O.Contains(id);
}

public static bool LoadCameraData()
{
try
Expand All @@ -407,8 +437,23 @@ public static bool LoadCameraData()
return true;
}

public static void WriteCameraData(byte[] camByte)
{
WriteBytes(BaseAddress + 0x33C6D6, camByte);
WriteBytes(BaseAddress + 0x33C6D7, camByte);
}

public static void PowercamHack()
{
// Override camera with preferred camera preset if camera state is CLEAN
if (PowerCamStyleStage == PowerCameraStyleStage.CLEAN)
{
// We've changed it, set Dirty
PowerCamStyleStage = PowerCameraStyleStage.DIRTY;
WriteCameraData(new byte[] { preferredCameraStyle });

}

// Animation index is -1 when the game is transitioning which is just about perfect
// Only override camera reset (flag 0x08) when the game is transitioning
// Works before entering Castle Grounds and literally any level transition
Expand All @@ -418,15 +463,18 @@ public static void PowercamHack()
WriteBytes(BaseAddress + 0x33C84B, new byte[] { (byte)(CameraState[0] & ~(0x8)) });
}

if (CameraState[0] == 0xA2)
if ((CameraState[0] & 0xA2) >= 0xA2 && (CameraState[2] & 0x0C) > 0)
{
// EDGE CASE. Sometimes the bugged first person camera happens
// when using Powercam and the only workaround was to just
// knock down the single edge case when it happens.
// EDGE CASES
// Mario keeps stuck in first person mode when camera is frozen.
// Oh No!

// This edge case happens only when the camera is hard-frozen
// and we're in first person with overrides enabled
WriteBytes(BaseAddress + 0x33C84B, new byte[] { 0x81 });
// and we're in first person, so just knock down the following

// NOTE: I *HATE* UNALIGNED WRITES/READS
// TODO: Find a way to perform better unaligned writes
WriteBytes(BaseAddress + 0x33C849, new byte[] { 0x00 });
}
else if (CameraFrozen && ((CameraState[0] & 0x80) != 0x20))
{
Expand All @@ -441,6 +489,8 @@ public static void PowercamHack()
// Glitchy: Camera status is actually a flag, which means we just need to take away
// the first person flag to restore, so it doesn't do a false alarm on newly
// loaded emulator instances (freezing camera Wayyyyyyyy up in the sky)

// Actually this has a different fix and I'll be implementing this into auto Powercam
byte[] data = { (byte)(CameraState[0] & ~(0x20)) };
WriteBytes(BaseAddress + 0x33C84B, data);
}
Expand Down Expand Up @@ -629,6 +679,7 @@ public static void LoadAddonsFromFolder(string path = "")
// AppDomains are incredibly messy
// Let's just hope you don't download anything suspicious
// HEAVILY considering moving back the Addon namespace back to .netFX
// ^ already did LOL

AddonErrorsBuilder = new StringBuilder();
_ = new ToolStripMenuItem("Addons");
Expand Down Expand Up @@ -920,11 +971,5 @@ public async static void PerformUpdate()
#endregion

public static bool GetKey(Keys vKey) => GetAsyncKeyState(vKey) != 0;
public static bool GetKeyDown(Keys vKey)
{
short _keyState = GetAsyncKeyState(vKey);
Debug.WriteLine($"KeyState: {_keyState}");
return ((_keyState & 0x80) != 0) && ((_keyState & 1) == 0);
}
}
}
10 changes: 9 additions & 1 deletion M64MM2/MainForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 59 additions & 6 deletions M64MM2/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public partial class MainForm : Form
ExtraControlsForm extraControlsForm;
SettingsForm settingsForm;
LatestUpdateDialog ludForm;

ToolTip hint = new ToolTip();
Keys _heldKeys = Keys.None;


Expand All @@ -32,6 +32,7 @@ public partial class MainForm : Form
public MainForm()
{
InitializeComponent();
hint.IsBalloon = true;
Core.EmulatorSelected += (a, b) => { EmulatorSelected(a, b); };
MoreThanOneEmuFound += (a, b) => { MoreThanOneEmu(a, b); };
ToolStripMenuItem addons = new ToolStripMenuItem("Addons");
Expand Down Expand Up @@ -99,9 +100,10 @@ public MainForm()
{
foreach (CameraStyle style in camStyles)
{
cbCamStyles.Items.Add(style.Name);
cbCamStyles.Items.Add(style);
}
cbCamStyles.SelectedIndex = 0;
cbCamStyles.SelectedIndex = camStyles.FindIndex(x => x.Value == preferredCameraStyle);
cbCamStyles.DisplayMember = "Name";
cbCamStyles.Refresh();
}
else
Expand All @@ -110,6 +112,8 @@ public MainForm()
cbCamStyles.Enabled = false;
}
}

cbPowercam.Checked = prePowercam;
}

void Update(object sender, EventArgs e)
Expand All @@ -121,6 +125,7 @@ void Update(object sender, EventArgs e)
Text = Resources.programName + " " + Application.ProductVersion + Resources.prereleaseString;
lblProgramStatus.Text = Resources.programStatus1;
FindEmuProcess();
PowerCamStyleStage = PowerCameraStyleStage.UNSET;
return;
}

Expand All @@ -140,6 +145,10 @@ void Update(object sender, EventArgs e)
if (CurrentLevelID < 3)
{
lblProgramStatus.Text = Resources.programStatusAwaitingLevel + "0x" + BaseAddress.ToString("X8");
if (Core.CameraStyle[0] == 0x00 && PowerCamStyleStage == PowerCameraStyleStage.UNSET)
{
PowerCamStyleStage = PowerCameraStyleStage.CLEAN;
}
return;
}

Expand All @@ -160,8 +169,24 @@ void Update(object sender, EventArgs e)
// in-game timer in that case
UpdateCoreEntityAddress();

if (CoreEntityAddress > 0 &&
Core.CameraStyle[0] != 0x00 &&
PowerCamStyleStage == PowerCameraStyleStage.UNSET)
{
PowerCamStyleStage = PowerCameraStyleStage.DIRTY;
if (CoreEntityAddress > 0 &&
WillLevelZoomOut(CurrentLevelID) &&
cbPowercam.Checked)
{
ShowPowercamTooltip(false);
cbPowercam.Checked = false;
}

}


lblCameraCode.Text = "0x" + BitConverter.ToString(CameraState).Replace("-", "");
lblCameraStyle.Text = "0x" + BitConverter.ToString(Core.CameraStyle).Replace("-", "");

// Execute camera fixes (bugged first person hack) and Powercam
PowercamHack();
Expand All @@ -178,7 +203,6 @@ void Update(object sender, EventArgs e)
{
_heldKeys &= ~Keys.D2;
}
Debug.WriteLine($"Check time for Held, HeldKey: {_heldKeys}");
if (GetKey(Keys.LControlKey) || GetKey(Keys.RControlKey))
{

Expand Down Expand Up @@ -258,8 +282,7 @@ void ChangeCameraStyle(object sender, EventArgs e)

byte[] data = { camStyles[cbCamStyles.SelectedIndex].Value };

WriteBytes(BaseAddress + 0x33C6D6, data);
WriteBytes(BaseAddress + 0x33C6D7, data);
WriteCameraData(data);
}


Expand Down Expand Up @@ -332,6 +355,27 @@ void OpenAppearanceSettings(object sender, EventArgs e)
}
}

void ShowPowercamTooltip(bool inlevel)
{
hint.Hide(this);
BringToFront();
if (inlevel)
{
hint.ToolTipTitle = Resources.powercamIngameDirtyTitle;
hint.ToolTipIcon = ToolTipIcon.Info;
hint.Show(string.Empty, cbPowercam, 8, 8);
hint.Show(Resources.powercamIngameDirtyMsg, cbPowercam, 8, 8, 10000);
}
else
{
hint.ToolTipTitle = Resources.powercamPregameDirtyTitle;
hint.ToolTipIcon = ToolTipIcon.Warning;
hint.Show(string.Empty, cbPowercam, 8, 8);
hint.Show(Resources.powercamPregameDirtyMsg, cbPowercam, 8, 8, 10000);
}

}

void OpenAboutForm(object sender, EventArgs e)
{
AboutForm about = new AboutForm();
Expand Down Expand Up @@ -408,6 +452,15 @@ private async void checkForLatestUpdateToolStripMenuItem_Click(object sender, Ev

private void cbPowercam_CheckedChanged(object sender, EventArgs e)
{
if (CoreEntityAddress > 0 &&
WillLevelZoomOut(CurrentLevelID) &&
((CheckBox)sender).Checked)
{
ShowPowercamTooltip(true);
((CheckBox)sender).Checked = false;
return;
}

PowerCamEnabled = cbPowercam.Checked;
}

Expand Down

0 comments on commit e36906a

Please sign in to comment.