Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saves made after the prologue are not loadable #3

Open
yvanoff opened this issue Apr 7, 2021 · 2 comments
Open

Saves made after the prologue are not loadable #3

yvanoff opened this issue Apr 7, 2021 · 2 comments

Comments

@yvanoff
Copy link

yvanoff commented Apr 7, 2021

Saves can be made at any point in the game. Saves made while the game is in the prologue can be loaded correctly, without any problem (the game correctly loads the save file).

However, saves made during chapter 1 or 2 can't be loaded because the game crashes upon loading them. Confirmed on both Windows and Linux

Stacktrace for the crash is here: https://pastebin.com/KYGxWZXx

@yvanoff
Copy link
Author

yvanoff commented May 27, 2021

Commenting two months after is weird, but if it helps the issue is that _threads in NsScriptProcess isn't initialised properly (it has 16 elements but only 6 are initialised)
Trying to determine if it is normal that only 6 elements are initialised

@ym1234
Copy link

ym1234 commented Jun 13, 2021

You can fix this (and the saves disappearing issue) with this very hacky patch.

diff --git a/src/NitroSharp.NsScript/VM/NsScriptProcess.cs b/src/NitroSharp.NsScript/VM/NsScriptProcess.cs
index 5f2149d..bb6511c 100644
--- a/src/NitroSharp.NsScript/VM/NsScriptProcess.cs
+++ b/src/NitroSharp.NsScript/VM/NsScriptProcess.cs
@@ -84,7 +84,7 @@ namespace NitroSharp.NsScript.VM
         {
             VM = vm;
             Id = dump.Id;
-            _clockBase = (int)Math.Round(Stopwatch.Frequency / 1000.0d * dump.ClockBaseMs);
+            _clockBase = (long)Math.Round(Stopwatch.Frequency / 1000.0d * dump.ClockBaseMs);
 
             _threads = new ArrayBuilder<NsScriptThread>(16);
             _newThreads = new ArrayBuilder<uint>(8);
diff --git a/src/NitroSharp/Builtins.Graphics.cs b/src/NitroSharp/Builtins.Graphics.cs
index efeb91c..a893e97 100644
--- a/src/NitroSharp/Builtins.Graphics.cs
+++ b/src/NitroSharp/Builtins.Graphics.cs
@@ -366,7 +366,7 @@ namespace NitroSharp
         {
             if (Get(dialoguePage) is DialoguePage page)
             {
-                page.Append(_ctx, text, _ctx.ActiveProcess.FontConfig);
+                page.Append(_ctx, (text, _ctx.ActiveProcess.FontConfig));
             }
         }
 
diff --git a/src/NitroSharp/GameContext.cs b/src/NitroSharp/GameContext.cs
index 1c7c235..419c37b 100644
--- a/src/NitroSharp/GameContext.cs
+++ b/src/NitroSharp/GameContext.cs
@@ -168,7 +168,7 @@ namespace NitroSharp
                 vm.SystemVariables
             );
 
-            return new GameContext(
+            var gc = new GameContext(
                 logger,
                 logEventRecorder,
                 window,
@@ -182,6 +182,8 @@ namespace NitroSharp
                 vm, mainProcess,
                 saveManager
             );
+            saveManager.ReadCommonSaveData(gc);
+            return gc;
         }
 
         private static (Logger, LogEventRecorder) SetupLogging()
diff --git a/src/NitroSharp/Graphics/RenderItems/DialoguePage.cs b/src/NitroSharp/Graphics/RenderItems/DialoguePage.cs
index 6a9766a..2a1d4a4 100644
--- a/src/NitroSharp/Graphics/RenderItems/DialoguePage.cs
+++ b/src/NitroSharp/Graphics/RenderItems/DialoguePage.cs
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System;
 using System.Numerics;
 using NitroSharp.NsScript;
 using NitroSharp.NsScript.VM;
@@ -20,7 +21,7 @@ namespace NitroSharp.Graphics
         private readonly float _lineHeight;
         private readonly NsScriptThread _dialogueThread;
         private readonly TextLayout _layout;
-        private readonly List<string> _pxmlLines = new();
+        private readonly List<(string, FontConfiguration)> _pxmlLines = new();
         private readonly Queue<TextBufferSegment> _remainingSegments = new();
 
         private TypewriterAnimation? _animation;
@@ -45,7 +46,7 @@ namespace NitroSharp.Graphics
         public override EntityKind Kind => EntityKind.DialoguePage;
 
         public Vector4 Margin { get; }
-        public override bool IsIdle => _dialogueThread.DoneExecuting && LineRead;
+        public override bool IsIdle => (_dialogueThread is null || _dialogueThread.DoneExecuting) && LineRead;
         public bool LineRead { get; private set; }
         public bool DisableAnimation { get; set; }
 
@@ -58,37 +59,33 @@ namespace NitroSharp.Graphics
             _bounds = saveData.Bounds;
             _lineHeight = saveData.LineHeight;
             _layout = new TextLayout(_bounds?.Width, _bounds?.Height, _lineHeight);
-            _dialogueThread = loadCtx.Process.VmProcess.GetThread(saveData.DialogueThreadId);
-            Margin = saveData.Margin;
-
-            foreach (string pxmlLine in saveData.PXmlLines)
+            try
             {
-                _pxmlLines.Add(pxmlLine);
-                FontConfiguration fontConfig = loadCtx.Process.FontConfig;
-                var buffer = TextBuffer.FromPXmlString(pxmlLine, fontConfig);
-                foreach (TextBufferSegment seg in buffer.Segments)
-                {
-                    _remainingSegments.Enqueue(seg);
-                }
-            }
+                _dialogueThread = loadCtx.Process.VmProcess.GetThread(saveData.DialogueThreadId);
+            } catch (Exception e) { }
+            Margin = saveData.Margin;
 
+            Array.ForEach(saveData.PXmlLines, x => Load(loadCtx.GameContext, x));
             while (_remainingSegments.Count != saveData.SegmentsRemaining)
             {
                 ConsumeSegment(loadCtx.GameContext);
             }
-
             loadCtx.Rendering.Text.RequestGlyphs(_layout);
         }
 
-        public void Append(GameContext ctx, string pxmlLine, FontConfiguration fontConfig)
+        private void Load(GameContext ctx, (string, FontConfiguration) x)
         {
-            _pxmlLines.Add(pxmlLine);
-            var buffer = TextBuffer.FromPXmlString(pxmlLine, fontConfig);
+            _pxmlLines.Add((x.Item1, x.Item2.Clone()));
+            var buffer = TextBuffer.FromPXmlString(x.Item1, x.Item2);
             foreach (TextBufferSegment seg in buffer.Segments)
             {
                 _remainingSegments.Enqueue(seg);
             }
+        }
 
+        public void Append(GameContext ctx, (string, FontConfiguration) x)
+        {
+            Load(ctx, x);
             Advance(ctx);
             ctx.RenderContext.Text.RequestGlyphs(_layout);
             LineRead = false;
@@ -184,7 +181,7 @@ namespace NitroSharp.Graphics
         {
             _skipping = ctx.Skipping;
             bool advance = ctx.Advance || ctx.Skipping;
-            if (advance || _dialogueThread.DoneExecuting)
+            if (advance || _dialogueThread is null || _dialogueThread.DoneExecuting)
             {
                 LineRead = _remainingSegments.Count == 0 && _animation is null;
             }
@@ -210,6 +207,7 @@ namespace NitroSharp.Graphics
             }
 
             return;
+            // dead code
 
             RectangleF bb = _layout.BoundingBox;
             ctx.MainBatch.PushQuad(
@@ -278,7 +276,7 @@ namespace NitroSharp.Graphics
             Bounds = _bounds,
             LineHeight = _lineHeight,
             Margin = Margin,
-            DialogueThreadId = _dialogueThread.Id,
+            DialogueThreadId = _dialogueThread is null ? 0 : _dialogueThread.Id,
             PXmlLines = _pxmlLines.ToArray(),
             SegmentsRemaining = _remainingSegments.Count
         };
@@ -292,7 +290,7 @@ namespace NitroSharp.Graphics
         public float LineHeight { get; init; }
         public Vector4 Margin { get; init; }
         public uint DialogueThreadId { get; init; }
-        public string[] PXmlLines { get; init; }
+        public (string, FontConfiguration)[] PXmlLines { get; init; }
         public int SegmentsRemaining { get; init; }
 
         public EntitySaveData CommonEntityData => Common.EntityData;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants