summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'src/StardewModdingAPI/Framework')
-rw-r--r--src/StardewModdingAPI/Framework/InternalExtensions.cs22
-rw-r--r--src/StardewModdingAPI/Framework/SGame.cs27
2 files changed, 36 insertions, 13 deletions
diff --git a/src/StardewModdingAPI/Framework/InternalExtensions.cs b/src/StardewModdingAPI/Framework/InternalExtensions.cs
index 5199c72d..cadf6598 100644
--- a/src/StardewModdingAPI/Framework/InternalExtensions.cs
+++ b/src/StardewModdingAPI/Framework/InternalExtensions.cs
@@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using Microsoft.Xna.Framework.Graphics;
+using StardewValley;
namespace StardewModdingAPI.Framework
{
@@ -128,5 +130,25 @@ namespace StardewModdingAPI.Framework
deprecationManager.Warn(modName, nounPhrase, version, severity);
}
}
+
+ /****
+ ** Sprite batch
+ ****/
+ /// <summary>Get whether the sprite batch is between a begin and end pair.</summary>
+ /// <param name="spriteBatch">The sprite batch to check.</param>
+ /// <param name="reflection">The reflection helper with which to access private fields.</param>
+ public static bool IsOpen(this SpriteBatch spriteBatch, IReflectionHelper reflection)
+ {
+ // get field name
+ const string fieldName =
+#if SMAPI_FOR_WINDOWS
+ "inBeginEndPair";
+#else
+ "_beginCalled";
+#endif
+
+ // get result
+ return reflection.GetPrivateValue<bool>(Game1.spriteBatch, fieldName);
+ }
}
}
diff --git a/src/StardewModdingAPI/Framework/SGame.cs b/src/StardewModdingAPI/Framework/SGame.cs
index f8226529..7dae937b 100644
--- a/src/StardewModdingAPI/Framework/SGame.cs
+++ b/src/StardewModdingAPI/Framework/SGame.cs
@@ -38,7 +38,7 @@ namespace StardewModdingAPI.Framework
private readonly int MaxFailedDraws = 120; // roughly two seconds
/// <summary>The number of consecutive failed draws.</summary>
- private int FailedDraws = 0;
+ private int FailedDraws;
/// <summary>Whether the player has loaded a save and the world has finished initialising.</summary>
private bool IsWorldReady => this.AfterLoadTimer < 0;
@@ -956,6 +956,9 @@ namespace StardewModdingAPI.Framework
}
catch (Exception ex)
{
+ // log error
+ this.Monitor.Log($"An error occured in the overridden draw loop: {ex.GetLogSummary()}", LogLevel.Error);
+
// exit if irrecoverable
if (this.FailedDraws >= this.MaxFailedDraws)
{
@@ -964,22 +967,20 @@ namespace StardewModdingAPI.Framework
}
this.FailedDraws++;
- // log error
- this.Monitor.Log($"An error occured in the overridden draw loop: {ex.GetLogSummary()}", LogLevel.Error);
-
- // fix sprite batch
+ // recover sprite batch
try
{
- bool isSpriteBatchOpen =
-#if SMAPI_FOR_WINDOWS
- SGame.Reflection.GetPrivateValue<bool>(Game1.spriteBatch, "inBeginEndPair");
-#else
- SGame.Reflection.GetPrivateValue<bool>(Game1.spriteBatch, "_beginCalled");
-#endif
- if (isSpriteBatchOpen)
+ if (Game1.spriteBatch.IsOpen(SGame.Reflection))
{
this.Monitor.Log("Recovering sprite batch from error...", LogLevel.Trace);
- Game1.spriteBatch.End();
+ try
+ {
+ Game1.spriteBatch.End();
+ }
+ catch
+ {
+ Game1.spriteBatch = new SpriteBatch(this.GraphicsDevice); // sprite batch is broken, try replacing it
+ }
}
}
catch (Exception innerEx)