diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..73d1437 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,59 @@ +name: Build Simitone + +on: + workflow_dispatch: + inputs: + configuration: + description: 'Build configuration' + required: false + default: 'Release' + type: choice + options: + - Release + - Debug + +jobs: + build: + runs-on: windows-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Setup .NET 9 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + + - name: Run Protobuild + shell: pwsh + run: | + cd FreeSO/Other/libs/FSOMonoGame/ + ./protobuild.exe --generate + continue-on-error: true + + - name: Restore Simitone dependencies + run: dotnet restore Client/Simitone/Simitone.sln + + - name: Restore FreeSO dependencies + run: dotnet restore FreeSO/TSOClient/FreeSO.sln + continue-on-error: true + + - name: Restore Roslyn dependencies + shell: pwsh + run: | + cd FreeSO/TSOClient/FSO.SimAntics.JIT.Roslyn/ + dotnet restore + continue-on-error: true + + - name: Build + run: dotnet build Client/Simitone/Simitone.sln -c ${{ inputs.configuration || 'Release' }} --no-restore + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: SimitoneWindows-${{ inputs.configuration || 'Release' }} + path: Client/Simitone/Simitone.Windows/bin/${{ inputs.configuration || 'Release' }}/net9.0-windows/ + if-no-files-found: error diff --git a/Client/Simitone/Simitone.Client/GameController.cs b/Client/Simitone/Simitone.Client/GameController.cs index f127879..43b01f9 100644 --- a/Client/Simitone/Simitone.Client/GameController.cs +++ b/Client/Simitone/Simitone.Client/GameController.cs @@ -1,7 +1,10 @@ using FSO.Client; using FSO.Client.UI.Framework; +using FSO.Client.UI.Controls; using FSO.Common.Utils; +using FSO.Content; using Simitone.Client.UI.Screens; +using Simitone.Client.UI.Panels; using System; using System.Collections.Generic; using System.Linq; @@ -56,8 +59,75 @@ public static void EnterGameMode(string lotName, bool external) } } screen.Initialize(lotName, external); + + // Show notification about any failed content files + ShowFailedContentNotification(); }); } + + /// + /// Shows a notification to the user about any content files that failed to load. + /// This is called after entering game mode so the user can see which custom content + /// files are problematic. + /// + private static void ShowFailedContentNotification() + { + var failedFiles = Content.FailedContentFiles; + if (failedFiles == null || failedFiles.Count == 0) + return; + + var realFailures = failedFiles + .Where(f => f.ErrorType != "DebugInfo") + .GroupBy(f => f.Filename) + .Select(g => g.First()) + .ToList(); + + if (realFailures.Count == 0) + return; + + var message = new StringBuilder(); + message.AppendLine("Some custom content files could not be loaded:"); + message.AppendLine(); + + int displayCount = Math.Min(realFailures.Count, 3); + for (int i = 0; i < displayCount; i++) + { + var file = realFailures[i]; + string shortReason = file.ErrorType switch + { + "EndOfStream" => "truncated", + "InvalidData" => "invalid format", + "IOException" => "I/O error", + "CatalogError" => "catalog error", + "DecodeError" => "decode failed", + _ => file.ErrorType + }; + message.AppendLine($"• {file.Filename} ({shortReason})"); + } + + if (realFailures.Count > 3) + { + message.AppendLine($"... and {realFailures.Count - 3} more"); + } + + message.AppendLine(); + message.AppendLine("Common causes: corrupted files, missing .cfp files, or wrong format."); + message.AppendLine("The game will continue without these items."); + + // Show the alert + UIMobileAlert alert = null; + alert = new UIMobileAlert(new UIAlertOptions + { + Title = "Custom Content Warning", + Message = message.ToString(), + Buttons = UIAlertButton.Ok((btn) => + { + alert.Close(); + }) + }); + + UIScreen.GlobalShowDialog(alert, true); + } public static void EnterCAS() { diff --git a/Client/Simitone/Simitone.Client/SimitoneGame.cs b/Client/Simitone/Simitone.Client/SimitoneGame.cs index 52ca85b..c892112 100644 --- a/Client/Simitone/Simitone.Client/SimitoneGame.cs +++ b/Client/Simitone/Simitone.Client/SimitoneGame.cs @@ -47,11 +47,13 @@ public SimitoneGame() : base() FSOEnvironment.TexCompress = false; UILotControl.ShowSimanticsExceptions = !FSOEnvironment.Args.Contains("nosimantics-exc"); + FSOEnvironment.DPIScaleFactor = GlobalSettings.Default.DPIScaleFactor; + if (!FSOEnvironment.SoftwareKeyboard) { Graphics.SynchronizeWithVerticalRetrace = true; - Graphics.PreferredBackBufferWidth = GlobalSettings.Default.GraphicsWidth; - Graphics.PreferredBackBufferHeight = GlobalSettings.Default.GraphicsHeight; + Graphics.PreferredBackBufferWidth = (int)(GlobalSettings.Default.GraphicsWidth * FSOEnvironment.DPIScaleFactor); + Graphics.PreferredBackBufferHeight = (int)(GlobalSettings.Default.GraphicsHeight * FSOEnvironment.DPIScaleFactor); Graphics.HardwareModeSwitch = false; Graphics.ApplyChanges(); } @@ -82,6 +84,8 @@ void Window_ClientSizeChanged(object sender, EventArgs e) if (uiLayer?.CurrentUIScreen == null) return; uiLayer.SpriteBatch.ResizeBuffer(GlobalSettings.Default.GraphicsWidth, GlobalSettings.Default.GraphicsHeight); + GlobalSettings.Default.GraphicsWidth = (int)(width / FSOEnvironment.DPIScaleFactor); + GlobalSettings.Default.GraphicsHeight = (int)(height / FSOEnvironment.DPIScaleFactor); uiLayer.CurrentUIScreen.GameResized(); } diff --git a/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj b/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj index edbb044..f71772c 100644 --- a/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj +++ b/Client/Simitone/Simitone.Windows/Simitone.Windows.csproj @@ -9,6 +9,7 @@ Simitone 512 Icon.ico + app.manifest true diff --git a/Client/Simitone/Simitone.Windows/app.manifest b/Client/Simitone/Simitone.Windows/app.manifest new file mode 100644 index 0000000..36ed651 --- /dev/null +++ b/Client/Simitone/Simitone.Windows/app.manifest @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true/pm + + + + diff --git a/FreeSO b/FreeSO index f86bbd3..fc2781d 160000 --- a/FreeSO +++ b/FreeSO @@ -1 +1 @@ -Subproject commit f86bbd34b2112296ed786741f640a0535886d180 +Subproject commit fc2781dac55b2214d77da1b7f376e0e8b0f10869