Skip to content

Commit

Permalink
Add more tweaks and update in general
Browse files Browse the repository at this point in the history
  • Loading branch information
0x0ade committed Dec 5, 2018
1 parent c6bc8a5 commit 8723803
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 39 deletions.
2 changes: 1 addition & 1 deletion CelesteTAS-EverestInterop/CelesteTAS-EverestInterop.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="metadata.yaml">
<Content Include="everest.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
Expand Down
103 changes: 84 additions & 19 deletions CelesteTAS-EverestInterop/CelesteTASModule.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Celeste;
using Celeste.Mod;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Monocle;
Expand Down Expand Up @@ -102,7 +103,7 @@ public override void Load() {
Everest.Relinker.Modder = null;
using (MonoModder modder = Everest.Relinker.Modder) {

modder.MethodRewriter += PatchAddonsMethod;
modder.MethodRewriter += PatchAddons;

// Normal brain: Hardcoded relinker map.
// 0x0ade brain: Helper attribute, dynamically generated map.
Expand Down Expand Up @@ -168,12 +169,21 @@ public override void Load() {
Manager.GetMethod("UpdateInputs")
);

// Relink RunThreadWithLogging to Celeste.RunThread.RunThreadWithLogging because reflection invoke is slow.
h_RunThreadWithLogging = new Detour(
typeof(CelesteTASModule).GetMethod("RunThreadWithLogging"),
typeof(RunThread).GetMethod("RunThreadWithLogging", BindingFlags.NonPublic | BindingFlags.Static)
);

// The original mod adds a few lines of code into Monocle.Engine::Update.
On.Monocle.Engine.Update += Engine_Update;

// The original mod makes the MInput.Update call conditional and invokes UpdateInputs afterwards.
On.Monocle.MInput.Update += MInput_Update;

// The original mod makes RunThread.Start run synchronously.
On.Celeste.RunThread.Start += RunThread_Start;

// The original mod makes the base.Update call conditional.
// We need to use Detour for two reasons:
// 1. Expose the trampoline to be used for the base.Update call in MInput_Update
Expand All @@ -182,23 +192,65 @@ public override void Load() {
typeof(Game).GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic),
typeof(CelesteTASModule).GetMethod("Game_Update")
)).GenerateTrampoline<d_Game_Update>();

// Optional: Disable achievements, stats and terminal.
On.Celeste.Achievements.Register += Achievements_Register;
On.Celeste.Stats.Increment += Stats_Increment;
On.Monocle.Commands.Render += Commands_Render;
On.Monocle.Commands.HandleKey += Commands_HandleKey;
}

public static void Achievements_Register(On.Celeste.Achievements.orig_Register orig, Achievement achievement) {
if (Settings.DisableAchievements && Running)
return;
orig(achievement);
}

public static void Stats_Increment(On.Celeste.Stats.orig_Increment orig, Stat stat, int increment) {
if (Settings.DisableStats && Running)
return;
orig(stat, increment);
}

public static void Commands_Render(On.Monocle.Commands.orig_Render orig, Monocle.Commands self) {
if (Settings.DisableTerminal && Running)
return;
orig(self);
}

public static void Commands_HandleKey(On.Monocle.Commands.orig_HandleKey orig, Monocle.Commands self, Keys key) {
if (Settings.DisableTerminal && Running) {
switch (key) {
case Keys.OemTilde:
case Keys.Oem8:
case Keys.OemPeriod:
self.Open = false;
break;
}
return;
}
orig(self, key);
}

public override void Unload() {
if (CelesteAddons == null)
return;

h_Game_Update.Undo();
h_Game_Update.Free();
h_UpdateInputs.Dispose();
h_RunThreadWithLogging.Dispose();
On.Monocle.Engine.Update -= Engine_Update;
On.Monocle.MInput.Update -= MInput_Update;
h_Game_Update.Undo();
h_Game_Update.Free();
On.Celeste.RunThread.Start -= RunThread_Start;
h_Game_Update.Dispose();
On.Celeste.Achievements.Register -= Achievements_Register;
On.Celeste.Stats.Increment -= Stats_Increment;
On.Monocle.Commands.Render -= Commands_Render;
On.Monocle.Commands.HandleKey -= Commands_HandleKey;
}

private TypeDefinition td_Engine;
private MethodDefinition md_Engine_get_Scene;
public void PatchAddonsMethod(MonoModder modder, MethodDefinition method) {
public void PatchAddons(MonoModder modder, MethodDefinition method) {
if (!method.HasBody)
return;

Expand Down Expand Up @@ -238,6 +290,13 @@ public static void UpdateInputs() {
throw new Exception("Failed relinking UpdateInputs!");
}

public static Detour h_RunThreadWithLogging;
[MethodImpl(MethodImplOptions.NoInlining)]
public static void RunThreadWithLogging(Action method) {
// This gets relinked to Celeste.RunThread.RunThreadWithLogging
throw new Exception("Failed relinking RunThreadWithLogging!");
}

public static void Engine_Update(On.Monocle.Engine.orig_Update orig, Engine self, GameTime gameTime) {
SkipBaseUpdate = false;

Expand All @@ -249,23 +308,20 @@ public static void Engine_Update(On.Monocle.Engine.orig_Update orig, Engine self
// The original patch doesn't store FrameLoops in a local variable, but it's only updated in UpdateInputs anyway.
int loops = FrameLoops;

if (Settings.FastForwardMode == FastForwardMode.Max && loops > 10) {
// Loop without base.Update(), then call base.Update() once.
SkipBaseUpdate = true;
for (int i = 0; i < loops; i++) {
orig(self, gameTime);
}
SkipBaseUpdate = false;
// This _should_ work...
orig(self, gameTime);
SkipBaseUpdate = loops >= 10;

return;
}

loops = Math.Min(10, loops);
for (int i = 0; i < loops; i++) {
// Anything happening early on runs in the MInput.Update hook.
orig(self, gameTime);

if (i >= 8 && Engine.Scene?.Tracker.GetEntity<FinalBoss>() != null) {
break;
}
}

SkipBaseUpdate = false;
if (loops >= 10)
orig_Game_Update(self, gameTime);
}

public static void MInput_Update(On.Monocle.MInput.orig_Update orig) {
Expand Down Expand Up @@ -311,5 +367,14 @@ public enum State {
FrameStep = 4
}

public static void RunThread_Start(On.Celeste.RunThread.orig_Start orig, Action method, string name, bool highPriority) {
if (Running) {
RunThreadWithLogging(method);
return;
}

orig(method, name, highPriority);
}

}
}
9 changes: 3 additions & 6 deletions CelesteTAS-EverestInterop/CelesteTASModuleSettings.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Celeste.Mod;
using MonoMod.Detour;
using System;
using System.Collections.Generic;
using System.IO;
Expand All @@ -13,11 +12,9 @@ namespace TAS.EverestInterop {
public class CelesteTASModuleSettings : EverestModuleSettings {

public bool Enabled { get; set; } = true;
public FastForwardMode FastForwardMode { get; set; } = FastForwardMode.Locked;
public bool DisableAchievements { get; set; } = false;
public bool DisableStats { get; set; } = false;
public bool DisableTerminal { get; set; } = false;

}
public enum FastForwardMode {
Locked,
Max
}
}
1 change: 0 additions & 1 deletion CelesteTAS-EverestInterop/CelesteTASProxies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using Mono.Cecil.Cil;
using Monocle;
using MonoMod;
using MonoMod.Detour;
using MonoMod.InlineRT;
using MonoMod.Utils;
using System;
Expand Down
6 changes: 6 additions & 0 deletions CelesteTAS-EverestInterop/everest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Name: CelesteTAS
Version: 1.2.0
DLL: CelesteTAS-EverestInterop.dll
Dependencies:
- Name: Everest
Version: 1.600.0
6 changes: 0 additions & 6 deletions CelesteTAS-EverestInterop/metadata.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion Everest
Submodule Everest updated 88 files
+33 −14 Celeste.Mod.mm/Celeste.Mod.mm.csproj
+17 −15 Celeste.Mod.mm/Content/Dialog/English.txt
+69 −0 Celeste.Mod.mm/Content/Dialog/French.txt
+ Celeste.Mod.mm/Content/Graphics/Atlases/Gui/emoji/checkpoint.m.png
+65 −20 Celeste.Mod.mm/Mod/Core/CoreModule.cs
+14 −2 Celeste.Mod.mm/Mod/Core/CoreModuleSettings.cs
+28 −0 Celeste.Mod.mm/Mod/Entities/BadelineOldsiteEnd.cs
+44 −0 Celeste.Mod.mm/Mod/Entities/DialogCutscene.cs
+33 −0 Celeste.Mod.mm/Mod/Entities/DialogCutsceneTrigger.cs
+3 −3 Celeste.Mod.mm/Mod/Entities/FlagTrigger.cs
+39 −0 Celeste.Mod.mm/Mod/Entities/GiveUpHint.cs
+23 −0 Celeste.Mod.mm/Mod/Entities/SpaceControllerBlocker.cs
+348 −0 Celeste.Mod.mm/Mod/Entities/TriggerSpikesOriginal.cs
+2 −0 Celeste.Mod.mm/Mod/Everest/Emoji.cs
+136 −164 Celeste.Mod.mm/Mod/Everest/Everest.Content.cs
+526 −0 Celeste.Mod.mm/Mod/Everest/Everest.DebugRC.cs
+21 −13 Celeste.Mod.mm/Mod/Everest/Everest.Discord.cs
+38 −23 Celeste.Mod.mm/Mod/Everest/Everest.Loader.cs
+11 −17 Celeste.Mod.mm/Mod/Everest/Everest.Update.cs
+42 −8 Celeste.Mod.mm/Mod/Everest/Everest.cs
+75 −1 Celeste.Mod.mm/Mod/Everest/Extensions.cs
+139 −81 Celeste.Mod.mm/Mod/Everest/ModAsset.cs
+20 −0 Celeste.Mod.mm/Mod/Helpers/EndUserException.cs
+3 −2 Celeste.Mod.mm/Mod/Helpers/FakeAssembly.cs
+55 −0 Celeste.Mod.mm/Mod/Helpers/SafeRoutine.cs
+270 −6 Celeste.Mod.mm/Mod/Meta/MapMeta.cs
+16 −12 Celeste.Mod.mm/Mod/Module/EverestModuleMetadata.cs
+0 −1 Celeste.Mod.mm/Mod/UI/OuiHelper_ChapterSelect_LevelSet.cs
+57 −0 Celeste.Mod.mm/Mod/UI/OuiHelper_ChapterSelect_Reload.cs
+32 −7 Celeste.Mod.mm/Mod/UI/OuiMapList.cs
+3 −3 Celeste.Mod.mm/Mod/UI/OuiModOptionString.cs
+0 −1 Celeste.Mod.mm/Mod/UI/OuiModOptions.cs
+1 −1 Celeste.Mod.mm/Mod/UI/OuiVersionList.cs
+1 −1 Celeste.Mod.mm/Mod/UI/TextMenuExt.cs
+320 −26 Celeste.Mod.mm/MonoModRules.cs
+1 −1 Celeste.Mod.mm/Patches/AreaComplete.cs
+167 −79 Celeste.Mod.mm/Patches/AreaData.cs
+2 −3 Celeste.Mod.mm/Patches/AreaKey.cs
+7 −2 Celeste.Mod.mm/Patches/AreaStats.cs
+55 −6 Celeste.Mod.mm/Patches/Audio.cs
+3 −3 Celeste.Mod.mm/Patches/Autotiler.cs
+90 −0 Celeste.Mod.mm/Patches/BadelineOldsite.cs
+19 −0 Celeste.Mod.mm/Patches/BinaryPacker.cs
+51 −0 Celeste.Mod.mm/Patches/CassetteBlock.cs
+121 −0 Celeste.Mod.mm/Patches/CassetteBlockManager.cs
+16 −2 Celeste.Mod.mm/Patches/Celeste.cs
+39 −0 Celeste.Mod.mm/Patches/Cloud.cs
+4 −3 Celeste.Mod.mm/Patches/CompleteRenderer.cs
+51 −0 Celeste.Mod.mm/Patches/CrystalStaticSpinner.cs
+35 −0 Celeste.Mod.mm/Patches/Decal.cs
+8 −3 Celeste.Mod.mm/Patches/Dialog.cs
+52 −0 Celeste.Mod.mm/Patches/FireBall.cs
+5 −5 Celeste.Mod.mm/Patches/GameLoader.cs
+38 −0 Celeste.Mod.mm/Patches/HeartGem.cs
+166 −15 Celeste.Mod.mm/Patches/Level.cs
+19 −1 Celeste.Mod.mm/Patches/LevelEnter.cs
+5 −5 Celeste.Mod.mm/Patches/LevelExit.cs
+3 −3 Celeste.Mod.mm/Patches/LevelLoader.cs
+3 −3 Celeste.Mod.mm/Patches/MainMenuSmallButton.cs
+256 −0 Celeste.Mod.mm/Patches/MapData.cs
+10 −4 Celeste.Mod.mm/Patches/Monocle/Atlas.cs
+7 −0 Celeste.Mod.mm/Patches/Monocle/Calc.cs
+1 −1 Celeste.Mod.mm/Patches/Monocle/EntityList.cs
+81 −81 Celeste.Mod.mm/Patches/Monocle/MTexture.cs
+6 −6 Celeste.Mod.mm/Patches/Monocle/SpriteBank.cs
+4 −4 Celeste.Mod.mm/Patches/Monocle/VirtualTexture.cs
+4 −1 Celeste.Mod.mm/Patches/OuiChapterPanel.cs
+32 −7 Celeste.Mod.mm/Patches/OuiChapterSelect.cs
+3 −3 Celeste.Mod.mm/Patches/OuiFileSelectSlot.cs
+54 −3 Celeste.Mod.mm/Patches/OuiTitleScreen.cs
+39 −0 Celeste.Mod.mm/Patches/Player.cs
+15 −3 Celeste.Mod.mm/Patches/PlayerHair.cs
+84 −0 Celeste.Mod.mm/Patches/RotateSpinner.cs
+42 −21 Celeste.Mod.mm/Patches/SaveData.cs
+62 −0 Celeste.Mod.mm/Patches/Settings.cs
+82 −5 Celeste.Mod.mm/Patches/UserIO.cs
+0 −8 MiniInstaller/MiniInstaller.csproj
+21 −21 MiniInstaller/Program.cs
+0 −4 MiniInstaller/packages.config
+53 −21 default.nix
+ lib-stripped/Celeste.exe
+ lib/MonoMod.RuntimeDetour.HookGen.exe
+ lib/MonoMod.RuntimeDetour.dll
+ lib/MonoMod.Utils.dll
+ lib/MonoMod.exe
+0 −3 run-nuget.sh
+9 −0 shell.nix
+1 −1 travis/replace-version.sh
Binary file modified MMHOOK_Celeste.dll
Binary file not shown.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
# CelesteTAS-EverestInterop

## Everest interop for DevilSquirrel's CelesteTAS
## Everest mod for DevilSquirrel's CelesteTAS

### License: MIT

----

This mod loads [DevilSquirrel's CelesteTAS](https://github.com/ShootMe/CelesteTAS) `Celeste-Addons.dll` and makes it work with [Everest](https://github.com/EverestAPI/Everest).
This mod acts as a helper loading [DevilSquirrel's CelesteTAS](https://github.com/ShootMe/CelesteTAS) `Celeste-Addons.dll` using [Everest](https://github.com/EverestAPI/Everest).

Note that this mod is useless on its own - you need to place the [mod .zip](https://github.com/EverestAPI/CelesteTAS-EverestInterop/releases) into the `Mods` directory and the `Celeste-Addons.dll` into the Celeste installation directory, next to `Celeste.exe`.
1. Place the [mod .zip](https://github.com/EverestAPI/CelesteTAS-EverestInterop/releases) into the `Mods` directory.
2. Place the correct `Celeste-Addons.dll` into the Celeste installation directory, next to `Celeste.exe`.
3. Enable the mod in the in-game mod options.

Check the README of [DevilSquirrel's CelesteTAS](https://github.com/ShootMe/CelesteTAS) for how to set up CelesteTAS.
**For full CelesteTAS instructions, check README of [DevilSquirrel's CelesteTAS](https://github.com/ShootMe/CelesteTAS). Skip all dnSpy / patching steps.**

**This isn't officially supported and compatibility with CelesteTAS and / or "Celeste Studio" can break at any time in the future.**
This isn't officially supported and compatibility with CelesteTAS and / or "Celeste Studio" can break at any time in the future.

0 comments on commit 8723803

Please sign in to comment.