From 0c151bbe62d94eb26eadc4395bca54ec48891c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kry=C5=A1tof=20Jel=C3=ADnek?= <33201513+Krelyshy@users.noreply.github.com> Date: Tue, 30 Jan 2024 13:58:13 +0100 Subject: [PATCH 01/27] Update ReadMe.md - fixed grammar / typos --- ReadMe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index db242c5..a281ccd 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -16,14 +16,14 @@ You can find prebuilt version of the game on [itch.io](https://maddymakesgamesin ### Tools Used - [TrenchBroom](https://trenchbroom.github.io/): For Level Editing - - [Blender](https://www.blender.org/): For creating 3D Model + - [Blender](https://www.blender.org/): For creating 3D Models - [Aseprite](https://www.aseprite.org/): For drawing Textures ### Resources Used - [khronos glTF Tutorials](https://github.khronos.org/glTF-Tutorials/gltfTutorial/gltfTutorial_020_Skins.html#the-joint-matrices): To figure out how Mesh Skins/Bones work - [LearnOpenGL](https://learnopengl.com/Advanced-OpenGL/Depth-testing): For general rendering concepts / normalizing Depth - [Kenny's Input Prompts](https://kenney.nl/assets/input-prompts): For UI Button Prompts - - [Renogare](https://www.dafont.com/renogare.font): Font for Text + - [Renogare](https://www.dafont.com/renogare.font): Main font ### Created By ... - [Maddy Thorson](http://maddymakesgames.com/) From ea3a5b1296307f69b37c25b9311a1bb1e7d5496e Mon Sep 17 00:00:00 2001 From: Felipe Martins <78514924+Fehype@users.noreply.github.com> Date: Wed, 31 Jan 2024 02:41:40 -0300 Subject: [PATCH 02/27] Icons for the keyboard support. Adds support for keyboard icons. (C, X) --- Source/Controls.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/Controls.cs b/Source/Controls.cs index b6e3981..6fa0cda 100644 --- a/Source/Controls.cs +++ b/Source/Controls.cs @@ -84,13 +84,16 @@ public static void Consume() private static string GetPromptLocation(string name) { + var gamepadPure = Input.Controllers[0]; var gamepad = Input.Controllers[0].Gamepad; if (!prompts.TryGetValue(gamepad, out var list)) prompts[gamepad] = list = new(); if (!list.TryGetValue(name, out var lookup)) - list[name] = lookup = $"Controls/{GetControllerName(gamepad)}/{name}"; + list[name] = lookup = gamepadPure.Name == "Unknown" + ? $"Controls/PC/{name}" + : $"Controls/{GetControllerName(gamepad)}/{name}"; return lookup; } @@ -109,4 +112,4 @@ public static Subtexture GetPrompt(VirtualButton button) { return Assets.Subtextures.GetValueOrDefault(GetPromptLocation(button)); } -} \ No newline at end of file +} From ed686ed6b3cca9e853b29edd96da62ce068f9872 Mon Sep 17 00:00:00 2001 From: Felipe Martins <78514924+Fehype@users.noreply.github.com> Date: Wed, 31 Jan 2024 02:42:07 -0300 Subject: [PATCH 03/27] Sprites for keyboard icons. C & X --- Content/Sprites/Controls/PC/cancel.png | Bin 0 -> 2480 bytes Content/Sprites/Controls/PC/confirm.png | Bin 0 -> 2330 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Content/Sprites/Controls/PC/cancel.png create mode 100644 Content/Sprites/Controls/PC/confirm.png diff --git a/Content/Sprites/Controls/PC/cancel.png b/Content/Sprites/Controls/PC/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..170b55c530620a8370c3345b81f0bae297a95a8e GIT binary patch literal 2480 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 A`v3p{ literal 0 HcmV?d00001 From 38cefe336bbfd01a829104f7bb53de4adb39c47f Mon Sep 17 00:00:00 2001 From: psyGamer Date: Wed, 31 Jan 2024 10:47:38 +0100 Subject: [PATCH 04/27] Always check uniform exists before setting it --- Source/Actors/Badeline.cs | 2 +- Source/Actors/Player.cs | 2 +- Source/Graphics/Hair.cs | 2 +- Source/Graphics/Materials.cs | 20 +++++++++++++++++--- Source/Graphics/Skybox.cs | 12 ++++++++---- Source/Graphics/SpriteRenderer.cs | 12 ++++++++---- Source/Scenes/Overworld.cs | 15 ++++++++++----- Source/Scenes/World.cs | 9 ++++++--- 8 files changed, 52 insertions(+), 22 deletions(-) diff --git a/Source/Actors/Badeline.cs b/Source/Actors/Badeline.cs index b9cf559..05397ca 100644 --- a/Source/Actors/Badeline.cs +++ b/Source/Actors/Badeline.cs @@ -19,7 +19,7 @@ public Badeline() : base(Assets.Models["badeline"]) mat.Color = hairColor; mat.Effects = 0; } - mat.Set("u_silhouette_color", hairColor); + mat.SilhouetteColor = hairColor; } hair = new() diff --git a/Source/Actors/Player.cs b/Source/Actors/Player.cs index 2d8864d..02de9fe 100644 --- a/Source/Actors/Player.cs +++ b/Source/Actors/Player.cs @@ -629,7 +629,7 @@ public void SetHairColor(Color color) mat.Color = color; mat.Effects = 0; } - mat.Set("u_silhouette_color", color); + mat.SilhouetteColor = color; } Hair.Color = color; diff --git a/Source/Graphics/Hair.cs b/Source/Graphics/Hair.cs index 8bf1861..323be6d 100644 --- a/Source/Graphics/Hair.cs +++ b/Source/Graphics/Hair.cs @@ -154,7 +154,7 @@ public override void Render(ref RenderState state) state.ModelMatrix = was; Materials[0].Color = Color; - Materials[0].Set("u_silhouette_color", Color); + Materials[0].SilhouetteColor = Color; // draw hair var call = new DrawCommand(state.Camera.Target, mesh, Materials[0]) diff --git a/Source/Graphics/Materials.cs b/Source/Graphics/Materials.cs index abe4b72..e7bb2b5 100644 --- a/Source/Graphics/Materials.cs +++ b/Source/Graphics/Materials.cs @@ -25,7 +25,11 @@ public class DefaultMaterial : Material public DefaultMaterial(Texture? texture = null) : base(Assets.Shaders["Default"]) { - Debug.Assert(Shader != null && Shader.Has(MatrixUniformName), $"Shader '{Shader.Name}' is missing '{MatrixUniformName}' uniform"); + if (!(Shader?.Has(MatrixUniformName) ?? false)) + { + Log.Warning($"Shader '{Shader?.Name}' is missing '{MatrixUniformName}' uniform"); + } + Texture = texture; Color = Color.White; Effects = 1.0f; @@ -34,13 +38,23 @@ public DefaultMaterial(Texture? texture = null) public Matrix MVP { get => matrix; - set => Set(MatrixUniformName, matrix = value); + set + { + matrix = value; + if (Shader?.Has(MatrixUniformName) ?? false) + Set(MatrixUniformName, value); + } } public Matrix Model { get => model; - set => Set("u_model", model = value); + set + { + model = value; + if (Shader?.Has("u_model") ?? false) + Set("u_model", value); + } } public Texture? Texture diff --git a/Source/Graphics/Skybox.cs b/Source/Graphics/Skybox.cs index 43296fc..6637848 100644 --- a/Source/Graphics/Skybox.cs +++ b/Source/Graphics/Skybox.cs @@ -60,10 +60,14 @@ private static void AddFace(List verts, List indices, in Vec3 public void Render(in Camera camera, in Matrix transform, float size) { var mat = Matrix.CreateScale(size) * transform * camera.ViewProjection; - material.Set("u_matrix", mat); - material.Set("u_near", camera.NearPlane); - material.Set("u_far", camera.FarPlane); - material.Set("u_texture", Texture); + if (material.Shader?.Has("u_matrix") ?? false) + material.Set("u_matrix", mat); + if (material.Shader?.Has("u_near") ?? false) + material.Set("u_near", camera.NearPlane); + if (material.Shader?.Has("u_far") ?? false) + material.Set("u_far", camera.FarPlane); + if (material.Shader?.Has("u_texture") ?? false) + material.Set("u_texture", Texture); DrawCommand cmd = new(camera.Target, mesh, material) { diff --git a/Source/Graphics/SpriteRenderer.cs b/Source/Graphics/SpriteRenderer.cs index a49d0d6..b626cf8 100644 --- a/Source/Graphics/SpriteRenderer.cs +++ b/Source/Graphics/SpriteRenderer.cs @@ -58,13 +58,17 @@ public void Render(ref RenderState state, List sprites, bool postEffects spriteMesh.SetVertices(CollectionsMarshal.AsSpan(spriteVertices)); spriteMesh.SetIndices(CollectionsMarshal.AsSpan(spriteIndices)); - spriteMaterial.Set("u_matrix", state.Camera.ViewProjection); - spriteMaterial.Set("u_far", state.Camera.FarPlane); - spriteMaterial.Set("u_near", state.Camera.NearPlane); + if (spriteMaterial.Shader?.Has("u_matrix") ?? false) + spriteMaterial.Set("u_matrix", state.Camera.ViewProjection); + if (spriteMaterial.Shader?.Has("u_far") ?? false) + spriteMaterial.Set("u_far", state.Camera.FarPlane); + if (spriteMaterial.Shader?.Has("u_near") ?? false) + spriteMaterial.Set("u_near", state.Camera.NearPlane); foreach (var batch in spriteBatches) { - spriteMaterial.Set("u_texture", batch.Texture); + if (spriteMaterial.Shader?.Has("u_texture") ?? false) + spriteMaterial.Set("u_texture", batch.Texture); var call = new DrawCommand(state.Camera.Target, spriteMesh, spriteMaterial) { diff --git a/Source/Scenes/Overworld.cs b/Source/Scenes/Overworld.cs index f92cf41..1c11a63 100644 --- a/Source/Scenes/Overworld.cs +++ b/Source/Scenes/Overworld.cs @@ -328,11 +328,16 @@ public override void Render(Target target) Matrix.CreateRotationZ((state == States.Entering ? -1 : 1) * rotation * MathF.PI) * Matrix.CreateTranslation(position); - material.Set("u_matrix", matrix * camera.ViewProjection); - material.Set("u_near", camera.NearPlane); - material.Set("u_far", camera.FarPlane); - material.Set("u_texture", it.Target); - material.Set("u_texture_sampler", new TextureSampler(TextureFilter.Linear, TextureWrap.ClampToEdge, TextureWrap.ClampToEdge)); + if (material.Shader?.Has("u_matrix") ?? false) + material.Set("u_matrix", matrix * camera.ViewProjection); + if (material.Shader?.Has("u_near") ?? false) + material.Set("u_near", camera.NearPlane); + if (material.Shader?.Has("u_far") ?? false) + material.Set("u_far", camera.FarPlane); + if (material.Shader?.Has("u_texture") ?? false) + material.Set("u_texture", it.Target); + if (material.Shader?.Has("u_texture_sampler") ?? false) + material.Set("u_texture_sampler", new TextureSampler(TextureFilter.Linear, TextureWrap.ClampToEdge, TextureWrap.ClampToEdge)); var cmd = new DrawCommand(target, mesh, material) { diff --git a/Source/Scenes/World.cs b/Source/Scenes/World.cs index db3dcc1..9be6171 100644 --- a/Source/Scenes/World.cs +++ b/Source/Scenes/World.cs @@ -830,9 +830,12 @@ private void ApplyPostEffects() // apply post fx postMaterial.SetShader(Assets.Shaders["Edge"]); - postMaterial.Set("u_depth", Camera.Target.Attachments[1]); - postMaterial.Set("u_pixel", new Vec2(1.0f / postCam.Target.Width, 1.0f / postCam.Target.Height)); - postMaterial.Set("u_edge", new Color(0x110d33)); + if (postMaterial.Shader?.Has("u_depth") ?? false) + postMaterial.Set("u_depth", Camera.Target.Attachments[1]); + if (postMaterial.Shader?.Has("u_pixel") ?? false) + postMaterial.Set("u_pixel", new Vec2(1.0f / postCam.Target.Width, 1.0f / postCam.Target.Height)); + if (postMaterial.Shader?.Has("u_edge") ?? false) + postMaterial.Set("u_edge", new Color(0x110d33)); batch.PushMaterial(postMaterial); batch.Image(Camera.Target.Attachments[0], Color.White); batch.Render(postTarget); From c734524e0362f6d3637a4df06feba90af838a9fb Mon Sep 17 00:00:00 2001 From: Noel Date: Wed, 31 Jan 2024 12:42:49 -0800 Subject: [PATCH 05/27] tweak backside of falling block to make grabless possible --- Content/Maps/1.map | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Content/Maps/1.map b/Content/Maps/1.map index 2bcf466..be97170 100644 --- a/Content/Maps/1.map +++ b/Content/Maps/1.map @@ -14991,12 +14991,12 @@ "_tb_layer" "3" // brush 0 { -( 3136 3168 480 ) ( 3136 3169 480 ) ( 3136 3168 481 ) rock_1 0 0 0 1 1 -( 3040 3360 480 ) ( 3040 3360 481 ) ( 3041 3360 480 ) rock_1 0 0 0 1 1 -( 3040 3168 288 ) ( 3041 3168 288 ) ( 3040 3169 288 ) rock_1 0 0 0 1 1 -( 3136 3296 480 ) ( 3136 3297 480 ) ( 3137 3296 480 ) wall_ruined_6 -64 0 0 1 1 -( 3136 3518 512 ) ( 3137 3518 512 ) ( 3136 3518 513 ) wood_4 0 0 0 1 1 -( 3264 3296 512 ) ( 3264 3296 513 ) ( 3264 3297 512 ) rock_1 0 0 0 1 1 +( 3136 3360 480 ) ( 3136 3424 288 ) ( 3136 3518 288 ) rock_1 0 0 0 1 1 +( 3264 3360 480 ) ( 3264 3424 288 ) ( 3136 3424 288 ) rock_1 0 0 0 1 1 +( 3264 3424 288 ) ( 3264 3518 288 ) ( 3136 3518 288 ) rock_1 0 0 0 1 1 +( 3136 3518 480 ) ( 3264 3518 480 ) ( 3264 3360 480 ) wall_ruined_6 -64 0 0 1 1 +( 3264 3518 288 ) ( 3264 3518 480 ) ( 3136 3518 480 ) wood_4 0 0 0 1 1 +( 3264 3360 480 ) ( 3264 3518 480 ) ( 3264 3518 288 ) rock_1 0 0 0 1 1 } } // entity 657 From 5c8e6f020e181b250a71d198bb0fc4b6829323d4 Mon Sep 17 00:00:00 2001 From: Felipe Martins <78514924+Fehype@users.noreply.github.com> Date: Wed, 31 Jan 2024 19:04:11 -0300 Subject: [PATCH 06/27] Update Controls.cs --- Source/Controls.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Controls.cs b/Source/Controls.cs index 6fa0cda..49ff113 100644 --- a/Source/Controls.cs +++ b/Source/Controls.cs @@ -84,16 +84,16 @@ public static void Consume() private static string GetPromptLocation(string name) { - var gamepadPure = Input.Controllers[0]; - var gamepad = Input.Controllers[0].Gamepad; + var gamepadPure = Input.Controllers[0]; + var gamepad = gamepadPure.Gamepad; if (!prompts.TryGetValue(gamepad, out var list)) prompts[gamepad] = list = new(); if (!list.TryGetValue(name, out var lookup)) - list[name] = lookup = gamepadPure.Name == "Unknown" - ? $"Controls/PC/{name}" - : $"Controls/{GetControllerName(gamepad)}/{name}"; + list[name] = lookup = !gamepadPure.Connected + ? $"Controls/PC/{name}" + : $"Controls/{GetControllerName(gamepad)}/{name}"; return lookup; } From f4f0a198e7d9629e3c641caab42e72118536404d Mon Sep 17 00:00:00 2001 From: Noel Date: Wed, 31 Jan 2024 15:26:33 -0800 Subject: [PATCH 07/27] handle corrupted save data; log error but continue normally --- Source/Save.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/Save.cs b/Source/Save.cs index f85fbce..036aa9d 100644 --- a/Source/Save.cs +++ b/Source/Save.cs @@ -154,7 +154,15 @@ public static void Serialize(Stream stream, Save instance) public static Save? Deserialize(string data) { - return JsonSerializer.Deserialize(data, SaveContext.Default.Save); + try + { + return JsonSerializer.Deserialize(data, SaveContext.Default.Save); + } + catch (Exception e) + { + Log.Error(e.ToString()); + return null; + } } } From b0e6f0388ac486a100c20c7b0c483a494d13f79f Mon Sep 17 00:00:00 2001 From: Noel Date: Wed, 31 Jan 2024 15:55:54 -0800 Subject: [PATCH 08/27] save to a temp file, validate it, then copy to actual save to avoid any data corruption --- Source/Game.cs | 5 +---- Source/Save.cs | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Source/Game.cs b/Source/Game.cs index 89c0fe8..6ae28c2 100644 --- a/Source/Game.cs +++ b/Source/Game.cs @@ -167,10 +167,7 @@ public override void Update() // perform game save between transitions if (transition.Saving) - { - using var stream = File.Create(Path.Join(App.UserPath, Save.FileName)); - Save.Serialize(stream, Save.Instance); - } + Save.Instance.SaveToFile(); // perform transition switch (transition.Mode) diff --git a/Source/Save.cs b/Source/Save.cs index 036aa9d..befdd1a 100644 --- a/Source/Save.cs +++ b/Source/Save.cs @@ -147,6 +147,26 @@ public void SyncSettings() Audio.SetVCAVolume("vca:/sfx", Calc.Clamp(SfxVolume / 10.0f, 0, 1)); } + public void SaveToFile() + { + var savePath = Path.Join(App.UserPath, FileName); + var tempPath = Path.Join(App.UserPath, FileName + ".backup"); + + // first save to a temporary file + { + using var stream = File.Create(tempPath); + Serialize(stream, this); + stream.Flush(); + } + + // validate that the temp path worked, and overwride existing if it did. + if (File.Exists(tempPath) && + Deserialize(File.ReadAllText(tempPath)) != null) + { + File.Copy(tempPath, savePath, true); + } + } + public static void Serialize(Stream stream, Save instance) { JsonSerializer.Serialize(stream, instance, SaveContext.Default.Save); From f2753a415bba1b30815b56d76ff2eacaba1221db Mon Sep 17 00:00:00 2001 From: Amanda Martins Xavier Date: Wed, 31 Jan 2024 21:11:56 -0300 Subject: [PATCH 09/27] =?UTF-8?q?=F0=9F=92=9A=20CI:=20pipeline=20for=20all?= =?UTF-8?q?=20platforms?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 138 ++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..1bf9acd --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,138 @@ +name: Build for all platforms + +on: + push: + tags: + - '**' + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Setup .NET + uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.0.x + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + body: | + # Instructions: + + - Download and extract the zip file below according to your OS and machine + - Run the Celeste64 application from the extracted files + + # Requirements: + + - **Windows:** x64 or arm64 + - **Linux:** x64 or arm64 + - **Mac:** x64 or arm64 + - Minimum macOS Version: Monterey 12.7 (Unfortunately because of the [Foster framework](https://github.com/FosterFramework/Foster)) + draft: false + prerelease: false + + - name: Build for macOS (x64) + run: dotnet publish -r osx-x64 -p:ImportByWildcardBeforeSolution=false + + - name: Compress + run: cd bin/Release/net8.0/osx-x64/publish/ && zip -r celeste64-macos-x64.zip * + + - name: Upload + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./bin/Release/net8.0/osx-x64/publish/celeste64-macos-x64.zip + asset_name: celeste64-macos-x64.zip + asset_content_type: application/zip + + - name: Build for macOS (arm) + run: dotnet publish -r osx-arm64 -p:ImportByWildcardBeforeSolution=false + + - name: Compress + run: cd bin/Release/net8.0/osx-arm64/publish/ && zip -r celeste64-macos-arm.zip * + + - name: Upload + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./bin/Release/net8.0/osx-arm64/publish/celeste64-macos-arm.zip + asset_name: celeste64-macos-arm.zip + asset_content_type: application/zip + + - name: Build for Windows (x64) + run: dotnet publish -r win-x64 -p:ImportByWildcardBeforeSolution=false + + - name: Compress + run: cd bin/Release/net8.0/win-x64/publish/ && zip -r celeste64-win-x64.zip * + + - name: Upload + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./bin/Release/net8.0/win-x64/publish/celeste64-win-x64.zip + asset_name: celeste64-win-x64.zip + asset_content_type: application/zip + + - name: Build for Windows (arm) + run: dotnet publish -r win-arm64 -p:ImportByWildcardBeforeSolution=false + + - name: Compress + run: cd bin/Release/net8.0/win-arm64/publish/ && zip -r celeste64-win-arm.zip * + + - name: Upload + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./bin/Release/net8.0/win-arm64/publish/celeste64-win-arm.zip + asset_name: celeste64-win-arm.zip + asset_content_type: application/zip + + - name: Build for Linux (x64) + run: dotnet publish -r linux-x64 -p:ImportByWildcardBeforeSolution=false + + - name: Compress + run: cd bin/Release/net8.0/linux-x64/publish/ && zip -r celeste64-linux-x64.zip * + + - name: Upload + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./bin/Release/net8.0/linux-x64/publish/celeste64-linux-x64.zip + asset_name: celeste64-linux-x64.zip + asset_content_type: application/zip + + - name: Build for Linux (arm) + run: dotnet publish -r linux-arm64 -p:ImportByWildcardBeforeSolution=false + + - name: Compress + run: cd bin/Release/net8.0/linux-arm64/publish/ && zip -r celeste64-linux-arm.zip * + + - name: Upload + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./bin/Release/net8.0/linux-arm64/publish/celeste64-linux-arm.zip + asset_name: celeste64-linux-arm.zip + asset_content_type: application/zip \ No newline at end of file From 0d6ad05b2e20715bd183164748f06758f3a2081e Mon Sep 17 00:00:00 2001 From: Noel Date: Wed, 31 Jan 2024 16:44:56 -0800 Subject: [PATCH 10/27] use SelfContained flag in csproj --- Celeste64.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Celeste64.csproj b/Celeste64.csproj index 53e85f0..d87c696 100644 --- a/Celeste64.csproj +++ b/Celeste64.csproj @@ -3,13 +3,14 @@ WinExe net8.0 + x64 enable enable true 1.0.1 true true - x64 + true From 141ca2013a76eeb0cb9cd3b9dd1663464956687d Mon Sep 17 00:00:00 2001 From: DemoJameson Date: Thu, 1 Feb 2024 13:52:30 +0800 Subject: [PATCH 11/27] Fix wrong fmod libs are copied when running dotnet publish; Fixes #19 --- Celeste64.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Celeste64.csproj b/Celeste64.csproj index d87c696..23df0cd 100644 --- a/Celeste64.csproj +++ b/Celeste64.csproj @@ -19,15 +19,15 @@ - + - + - + From 593841acd38a76375cfd3e898f199b9c8e979684 Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Wed, 31 Jan 2024 22:27:33 -0800 Subject: [PATCH 12/27] default windowed size is 720p instead of 1080p --- Source/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Program.cs b/Source/Program.cs index f1f1fc7..853e9c7 100644 --- a/Source/Program.cs +++ b/Source/Program.cs @@ -22,7 +22,7 @@ public static void Main(string[] args) try { - App.Run(Game.GamePath, 1920, 1080); + App.Run(Game.GamePath, 1280, 720); } catch (Exception e) { From abc9c9c27a49e2e0a10bf45b06f1452b5023f814 Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Wed, 31 Jan 2024 23:00:34 -0800 Subject: [PATCH 13/27] bump to foster 0.1.15 --- Celeste64.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Celeste64.csproj b/Celeste64.csproj index 23df0cd..de4f0ef 100644 --- a/Celeste64.csproj +++ b/Celeste64.csproj @@ -14,7 +14,7 @@ - + From 96f1d36d8b4fb26a3538438e69adfb2690bd9548 Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Wed, 31 Jan 2024 23:13:17 -0800 Subject: [PATCH 14/27] Use Enum.GetValues instead for NativeAOT --- Source/Helpers/StateMachine.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Helpers/StateMachine.cs b/Source/Helpers/StateMachine.cs index 6c8c452..5419b5d 100644 --- a/Source/Helpers/StateMachine.cs +++ b/Source/Helpers/StateMachine.cs @@ -5,8 +5,8 @@ public unsafe sealed class StateMachine where TIndex : unmanaged, Enum where TEvent : unmanaged, Enum { - private static readonly int StateCount = Enum.GetValues(typeof(TIndex)).Length; - private static readonly int EventCount = Enum.GetValues(typeof(TEvent)).Length; + private static readonly int StateCount = Enum.GetValues().Length; + private static readonly int EventCount = Enum.GetValues().Length; private static int StateToIndex(TIndex state) => *(int*)(&state); private static int EventToIndex(TEvent state) => *(int*)(&state); From 3bf565ad191d3737535c63604cad7c7879a1f434 Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Wed, 31 Jan 2024 23:44:38 -0800 Subject: [PATCH 15/27] fix MSBuild warning about parenthesis --- Celeste64.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Celeste64.csproj b/Celeste64.csproj index de4f0ef..206d8e5 100644 --- a/Celeste64.csproj +++ b/Celeste64.csproj @@ -10,7 +10,7 @@ 1.0.1 true true - true + true @@ -19,15 +19,15 @@ - + - + - + From 54478373e1284a226fbc795c7da86c9c6ffd08bc Mon Sep 17 00:00:00 2001 From: JoshuaMadd <92428530+JoshuaMadd@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:58:22 +0100 Subject: [PATCH 16/27] Fix cassette not saving Fixed the game not properly saving and exiting the level after collecting a cassette without a map property when you're not in a subarea. This will allow map makers to end the level by picking up a cassette tape. --- Source/Actors/Player.cs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Source/Actors/Player.cs b/Source/Actors/Player.cs index 02de9fe..61a604f 100644 --- a/Source/Actors/Player.cs +++ b/Source/Actors/Player.cs @@ -2067,16 +2067,30 @@ private CoEnumerator StCassetteRoutine() if (cassette != null) { - if (World.Entry.Submap || !Assets.Maps.ContainsKey(cassette.Map)) + if (World.Entry.Submap) { - Game.Instance.Goto(new Transition() + Game.Instance.Goto(new Transition() { Mode = Transition.Modes.Pop, ToPause = true, ToBlack = new SpotlightWipe(), StopMusic = true }); - } + } + //Saves and quits game if you collect a cassette with an empty map property when you're not in a submap + else if (!Assets.Maps.ContainsKey(cassette.Map)) + { + Game.Instance.Goto(new Transition() + { + Mode = Transition.Modes.Replace, + Scene = () => new Overworld(true), + ToPause = true, + ToBlack = new SpotlightWipe(), + FromBlack = new SlideWipe(), + StopMusic = true, + Saving = true + }); + } else { Game.Instance.Goto(new Transition() @@ -2282,4 +2296,4 @@ public bool CeilingCheck(out Vec3 pushout) public void Stop() => velocity = Vec3.Zero; #endregion -} \ No newline at end of file +} From 74fc6132a469a5919792f3b2480776ad9f79ab3c Mon Sep 17 00:00:00 2001 From: Noa Date: Thu, 1 Feb 2024 12:37:46 -0600 Subject: [PATCH 17/27] Change anti-spike-climb-hop check to a threshold of 4 units --- Source/Actors/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Actors/Player.cs b/Source/Actors/Player.cs index 02de9fe..d0482d6 100644 --- a/Source/Actors/Player.cs +++ b/Source/Actors/Player.cs @@ -1489,7 +1489,7 @@ private void StClimbingUpdate() // don't climb over ledges into spikes // (you can still climb up into spikes if they're on the same wall as you) - if (move.Z > 0 && World.Overlaps(Position + Vec3.UnitZ * 6 + forward * (ClimbCheckDist + 1))) + if (move.Z > 0 && World.Overlaps(Position + Vec3.UnitZ * ClimbCheckDist + forward * (ClimbCheckDist + 1))) move.Z = 0; // don't move left/right around into a spikes From 805f1353f410b1cef529208ae8427eba5eb4b85d Mon Sep 17 00:00:00 2001 From: TheDrawingCoding-Gamer Date: Thu, 1 Feb 2024 18:45:56 -0500 Subject: [PATCH 18/27] forget selected index in pause menu --- Source/Scenes/World.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Scenes/World.cs b/Source/Scenes/World.cs index 9be6171..1a5cb71 100644 --- a/Source/Scenes/World.cs +++ b/Source/Scenes/World.cs @@ -370,6 +370,7 @@ public override void Update() { if (Controls.Pause.Pressed || Controls.Cancel.Pressed) { + pauseMenu.Index = 0; SetPaused(false); Audio.Play(Sfx.ui_unpause); } @@ -859,4 +860,4 @@ private void RenderModels(ref RenderState state, List models, ModelF it.Model.Render(ref state); } } -} \ No newline at end of file +} From f3d3edc315da659607c2df7af1c5f9b082344ff9 Mon Sep 17 00:00:00 2001 From: Noel Date: Thu, 1 Feb 2024 16:25:34 -0800 Subject: [PATCH 19/27] show version number on overworld & when paused --- Source/Scenes/Overworld.cs | 7 +++++-- Source/Scenes/World.cs | 6 ++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Source/Scenes/Overworld.cs b/Source/Scenes/Overworld.cs index 1c11a63..fbe5ec0 100644 --- a/Source/Scenes/Overworld.cs +++ b/Source/Scenes/Overworld.cs @@ -382,8 +382,11 @@ public override void Render(Target target) var width = 0.0f; UI.Prompt(batch, Controls.Cancel, cancelPrompt, at, out width, 1.0f); at.X -= width + 8 * Game.RelativeScale; - UI.Prompt(batch, Controls.Confirm, "Confirm", at, out _, 1.0f); - } + UI.Prompt(batch, Controls.Confirm, "Confirm", at, out _, 1.0f); + + // show version number on Overworld as well + UI.Text(batch, Game.VersionString, bounds.BottomLeft + new Vec2(4, -4) * Game.RelativeScale, new Vec2(0, 1), Color.White * 0.25f); + } if (cameraCloseUpEase > 0) { diff --git a/Source/Scenes/World.cs b/Source/Scenes/World.cs index 9be6171..a35a55f 100644 --- a/Source/Scenes/World.cs +++ b/Source/Scenes/World.cs @@ -792,6 +792,12 @@ public override void Render(Target target) UI.Strawberries(batch, Save.CurrentRecord.Strawberries.Count, Vec2.Zero); batch.PopMatrix(); } + + // show version number when paused / in ending area + if (IsInEndingArea || Paused) + { + UI.Text(batch, Game.VersionString, bounds.BottomLeft + new Vec2(4, -4) * Game.RelativeScale, new Vec2(0, 1), Color.White * 0.25f); + } } // overlay From 138f36450a561837396f17651019a8fbe8ccc9d4 Mon Sep 17 00:00:00 2001 From: Amanda Martins Xavier Date: Thu, 1 Feb 2024 21:31:39 -0300 Subject: [PATCH 20/27] =?UTF-8?q?=F0=9F=92=9A=20Refactor:=20simultaneous?= =?UTF-8?q?=20build?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 153 +++++++++--------------------------- 1 file changed, 35 insertions(+), 118 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1bf9acd..ddd793f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build for all platforms +name: Build and build on: push: @@ -7,9 +7,11 @@ on: jobs: build: - - runs-on: ubuntu-latest - + strategy: + matrix: + platform: [macos-latest, ubuntu-latest, windows-latest] + + runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v3 @@ -18,121 +20,36 @@ jobs: with: dotnet-version: 8.0.x - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref }} - body: | - # Instructions: - - - Download and extract the zip file below according to your OS and machine - - Run the Celeste64 application from the extracted files - - # Requirements: - - - **Windows:** x64 or arm64 - - **Linux:** x64 or arm64 - - **Mac:** x64 or arm64 - - Minimum macOS Version: Monterey 12.7 (Unfortunately because of the [Foster framework](https://github.com/FosterFramework/Foster)) - draft: false - prerelease: false - - - name: Build for macOS (x64) - run: dotnet publish -r osx-x64 -p:ImportByWildcardBeforeSolution=false - - - name: Compress - run: cd bin/Release/net8.0/osx-x64/publish/ && zip -r celeste64-macos-x64.zip * - - - name: Upload - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./bin/Release/net8.0/osx-x64/publish/celeste64-macos-x64.zip - asset_name: celeste64-macos-x64.zip - asset_content_type: application/zip - - - name: Build for macOS (arm) - run: dotnet publish -r osx-arm64 -p:ImportByWildcardBeforeSolution=false - - - name: Compress - run: cd bin/Release/net8.0/osx-arm64/publish/ && zip -r celeste64-macos-arm.zip * - - - name: Upload - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./bin/Release/net8.0/osx-arm64/publish/celeste64-macos-arm.zip - asset_name: celeste64-macos-arm.zip - asset_content_type: application/zip - - - name: Build for Windows (x64) - run: dotnet publish -r win-x64 -p:ImportByWildcardBeforeSolution=false - - - name: Compress - run: cd bin/Release/net8.0/win-x64/publish/ && zip -r celeste64-win-x64.zip * - - - name: Upload - uses: actions/upload-release-asset@v1 + - name: Build env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./bin/Release/net8.0/win-x64/publish/celeste64-win-x64.zip - asset_name: celeste64-win-x64.zip - asset_content_type: application/zip - - - name: Build for Windows (arm) - run: dotnet publish -r win-arm64 -p:ImportByWildcardBeforeSolution=false - - - name: Compress - run: cd bin/Release/net8.0/win-arm64/publish/ && zip -r celeste64-win-arm.zip * + os: ${{ runner.os == 'Windows' && 'win' || runner.os == 'macOS' && 'osx' || 'linux' }} + run: | + dotnet publish -c Release -r ${{ env.os }}-x64 -p:ImportByWildcardBeforeSolution=false -o build && + cp -r Content build + + - name: Compress (Windows) + run: | + Compress-Archive build/* Celeste64-${{ github.ref_name }}-${{ runner.os }}-x64.zip + if: runner.os == 'Windows' - - name: Upload - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./bin/Release/net8.0/win-arm64/publish/celeste64-win-arm.zip - asset_name: celeste64-win-arm.zip - asset_content_type: application/zip - - - name: Build for Linux (x64) - run: dotnet publish -r linux-x64 -p:ImportByWildcardBeforeSolution=false + - name: Compress (macOS and Linux) + run: | + cd build && zip -r ../Celeste64-${{ github.ref_name }}-${{ runner.os }}-x64.zip * + if: runner.os != 'Windows' - - name: Compress - run: cd bin/Release/net8.0/linux-x64/publish/ && zip -r celeste64-linux-x64.zip * - - - name: Upload - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./bin/Release/net8.0/linux-x64/publish/celeste64-linux-x64.zip - asset_name: celeste64-linux-x64.zip - asset_content_type: application/zip - - - name: Build for Linux (arm) - run: dotnet publish -r linux-arm64 -p:ImportByWildcardBeforeSolution=false - - - name: Compress - run: cd bin/Release/net8.0/linux-arm64/publish/ && zip -r celeste64-linux-arm.zip * - - - name: Upload - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Release (GitHub) + uses: softprops/action-gh-release@v1 with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./bin/Release/net8.0/linux-arm64/publish/celeste64-linux-arm.zip - asset_name: celeste64-linux-arm.zip - asset_content_type: application/zip \ No newline at end of file + name: Release ${{ github.ref_name }} + body: | + # Instructions: + + - Download and extract the zip file below according to your computer + - Run the Celeste64 application from the extracted files + + # Requirements: + + - **Windows:** 10 or later, x64 + - **Linux:** [Distro support list](https://github.com/dotnet/core/blob/main/release-notes/8.0/supported-os.md), x64 + - **Mac:** Monterey or later, x64 Intel-based or Apple Silicon with Rosetta + files: Celeste64-${{ github.ref_name }}-${{ runner.os }}-x64.zip From bc32ae2379329d1e88a2eac0a4395344ff9ab55e Mon Sep 17 00:00:00 2001 From: TheDrawingCoding-Gamer Date: Thu, 1 Feb 2024 20:34:26 -0500 Subject: [PATCH 21/27] change where index reset --- Source/Scenes/World.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/Scenes/World.cs b/Source/Scenes/World.cs index 1a5cb71..f4fbfc3 100644 --- a/Source/Scenes/World.cs +++ b/Source/Scenes/World.cs @@ -370,7 +370,6 @@ public override void Update() { if (Controls.Pause.Pressed || Controls.Cancel.Pressed) { - pauseMenu.Index = 0; SetPaused(false); Audio.Play(Sfx.ui_unpause); } @@ -393,8 +392,10 @@ public void SetPaused(bool paused) Audio.Play(Sfx.ui_pause); pauseSnapshot = Audio.Play(Sfx.snapshot_pause); } - else + else { + pauseMenu.Index = 0; pauseSnapshot.Stop(); + } Controls.Consume(); Paused = paused; From 0d5b84255bfde7e884cbef745286248a4c5910f5 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Fri, 2 Feb 2024 15:45:50 +0900 Subject: [PATCH 22/27] Fix typo in Game.cs happend -> happened --- Source/Game.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Game.cs b/Source/Game.cs index 6ae28c2..ccb75e0 100644 --- a/Source/Game.cs +++ b/Source/Game.cs @@ -322,7 +322,7 @@ public override void Render() private FMOD.RESULT MusicTimelineCallback(FMOD.Studio.EVENT_CALLBACK_TYPE type, IntPtr _event, IntPtr parameters) { - // notify that an audio event happend (but handle it on the main thread) + // notify that an audio event happened (but handle it on the main thread) if (transitionStep == TransitionStep.None) audioBeatCounterEvent = true; return FMOD.RESULT.OK; From 47dc31b0cd6b5a25183d692d33159525d76d1ffd Mon Sep 17 00:00:00 2001 From: Jordan Christiansen Date: Fri, 2 Feb 2024 11:18:06 -0600 Subject: [PATCH 23/27] Change one face of this ramp to match nearby textures I think this face was meant to have the same wood_3 texture as its surroundings. It's mostly obscured by trees, so it was likely missed. However, the bright blue of rock_1 does show up well even when a small portion of the face is showing. --- Content/Maps/1.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content/Maps/1.map b/Content/Maps/1.map index be97170..2f44a14 100644 --- a/Content/Maps/1.map +++ b/Content/Maps/1.map @@ -3917,7 +3917,7 @@ } // brush 422 { -( 3456 3104 576 ) ( 3456 3105 576 ) ( 3456 3104 577 ) rock_1 0 0 0 1 1 +( 3456 3104 576 ) ( 3456 3105 576 ) ( 3456 3104 577 ) wood_3 0 0 0 1 1 ( 3456 3104 576 ) ( 3456 3104 577 ) ( 3457 3104 576 ) rock_1 0 0 0 1 1 ( 3584 3104 544 ) ( 3712 3616 288 ) ( 3584 3616 288 ) wall_ruined_2 0 0 0 1 1 ( 3456 3104 288 ) ( 3457 3104 288 ) ( 3456 3105 288 ) rock_1 0 0 0 1 1 From 96fe4b691aa4c59df05d98d1a4f9d7b030f5ebb8 Mon Sep 17 00:00:00 2001 From: JoshuaMadd Date: Sat, 3 Feb 2024 01:46:02 +0100 Subject: [PATCH 24/27] Added submenus and menu titles --- Source/Helpers/Menu.cs | 116 +++++++++++++++++++++++++++++++++-------- Source/Scenes/World.cs | 33 +++++++----- 2 files changed, 114 insertions(+), 35 deletions(-) diff --git a/Source/Helpers/Menu.cs b/Source/Helpers/Menu.cs index c9ca104..4e771de 100644 --- a/Source/Helpers/Menu.cs +++ b/Source/Helpers/Menu.cs @@ -1,4 +1,7 @@ +using System.Reflection.Emit; +using static Celeste64.Menu; + namespace Celeste64; public class Menu @@ -10,11 +13,27 @@ public abstract class Item { public virtual string Label { get; } = string.Empty; public virtual bool Selectable { get; } = true; - public virtual bool Pressed() => false; + public virtual bool Pressed() => false; public virtual void Slide(int dir) {} } - public class Spacer : Item + public class Submenu(string label, Menu mainMenu, Menu? submenu = null) : Item + { + private readonly string label = label; + public override string Label => label; + public override bool Pressed() { + if (submenu != null) { + Audio.Play(Sfx.ui_select); + mainMenu.Index = 0; + mainMenu.Title = submenu.Title; + mainMenu.addItemsToStack(submenu.getCurrentItems()); + return true; + } + return false; + } + } + + public class Spacer : Item { public override bool Selectable => false; } @@ -80,22 +99,56 @@ public int Index get => index; set => index = value; } - public bool Focused = true; + + public string Title { + get => title; + set => title = value; + } + + public bool Focused = true; private readonly SpriteFont font; - private readonly List items = []; - private int index = 0; + //Stack to keeps track of all menus before current menu + private readonly Stack> menuStack = new Stack>(); + private int index = 0; + private string title = string.Empty; public string UpSound = Sfx.ui_move; public string DownSound = Sfx.ui_move; - public Vec2 Size + protected List getCurrentItems() + { + return menuStack.Peek(); + } + + protected void addItemsToStack(List items) + { + menuStack.Push(items); + } + + public bool isInMainMenu() + { + return menuStack.Count == 1; + } + + public void closeSubmenus() + { + while (menuStack.Count > 1) { menuStack.Pop(); } + } + + public Vec2 Size { get { Vec2 size = Vec2.Zero; - foreach (var item in items) + if (!string.IsNullOrEmpty(title)) { + size.X = font.WidthOf(title); + size.Y += font.LineHeight; + size.Y += SpacerHeight + Spacing; + } + + foreach (var item in getCurrentItems()) { if (string.IsNullOrEmpty(item.Label)) { @@ -109,7 +162,7 @@ public Vec2 Size size.Y += Spacing; } - if (items.Count > 0) + if (getCurrentItems().Count > 0) size.Y -= Spacing; return size; @@ -119,17 +172,18 @@ public Vec2 Size public Menu() { font = Assets.Fonts.First().Value; + menuStack.Push(new List()); } public Menu Add(Item item) { - items.Add(item); + getCurrentItems().Add(item); return this; } public void Update() { - if (items.Count > 0 && Focused) + if (getCurrentItems().Count > 0 && Focused) { var was = index; var step = 0; @@ -139,45 +193,65 @@ public void Update() step = -1; index += step; - while (!items[(items.Count + index) % items.Count].Selectable) + while (!getCurrentItems()[(getCurrentItems().Count + index) % getCurrentItems().Count].Selectable) index += step; - index = (items.Count + index) % items.Count; + index = (getCurrentItems().Count + index) % getCurrentItems().Count; if (was != index) Audio.Play(step < 0 ? UpSound : DownSound); if (Controls.Menu.Horizontal.Negative.Pressed) - items[index].Slide(-1); + getCurrentItems()[index].Slide(-1); if (Controls.Menu.Horizontal.Positive.Pressed) - items[index].Slide(1); + getCurrentItems()[index].Slide(1); - if (Controls.Confirm.Pressed && items[index].Pressed()) + if (Controls.Confirm.Pressed && getCurrentItems()[index].Pressed()) Controls.Consume(); - } + if (Controls.Cancel.Pressed && !isInMainMenu()) + { + Audio.Play(Sfx.main_menu_toggle_off); + Index = 0; + menuStack.Pop(); + } + } } public void Render(Batcher batch, Vec2 position) { var size = Size; batch.PushMatrix(-size / 2); - for (int i = 0; i < items.Count; i ++) + + if(!string.IsNullOrEmpty(title)) + { + var at = position + new Vec2(size.X / 2, 0); + var text = title; + var justify = new Vec2(0.5f, 0); + var color = new Color(8421504); + + UI.Text(batch, text, at, justify, color); + + position.Y += font.LineHeight; + position.Y += SpacerHeight + Spacing; + } + + for (int i = 0; i < getCurrentItems().Count; i ++) { - if (string.IsNullOrEmpty(items[i].Label)) + if (string.IsNullOrEmpty(getCurrentItems()[i].Label)) { position.Y += SpacerHeight; continue; } var at = position + new Vec2(size.X / 2, 0); - var text = items[i].Label; + var text = getCurrentItems()[i].Label; var justify = new Vec2(0.5f, 0); var color = index == i && Focused ? (Time.BetweenInterval(0.1f) ? 0x84FF54 : 0xFCFF59) : Color.White; UI.Text(batch, text, at, justify, color); position.Y += font.LineHeight; - position.Y += Spacing; - } + position.Y += Spacing; + } batch.PopMatrix(); } } \ No newline at end of file diff --git a/Source/Scenes/World.cs b/Source/Scenes/World.cs index 88084dc..d37b692 100644 --- a/Source/Scenes/World.cs +++ b/Source/Scenes/World.cs @@ -76,22 +76,26 @@ public World(EntryInfo entry) strawbCounterWiggle = 0; // setup pause menu - { - pauseMenu.Add(new Menu.Option("Resume", () => SetPaused(false))); + { + pauseMenu.Title = "Paused"; + pauseMenu.Add(new Menu.Option("Resume", () => SetPaused(false))); pauseMenu.Add(new Menu.Option("Retry", () => { SetPaused(false); Audio.StopBus(Sfx.bus_dialog, false); Get()?.Kill(); - })); - pauseMenu.Add(new Menu.Spacer()); - pauseMenu.Add(new Menu.Toggle("Fullscreen", Save.Instance.ToggleFullscreen, () => Save.Instance.Fullscreen)); - pauseMenu.Add(new Menu.Toggle("Z-Guide", Save.Instance.ToggleZGuide, () => Save.Instance.ZGuide)); - pauseMenu.Add(new Menu.Toggle("Timer", Save.Instance.ToggleTimer, () => Save.Instance.SpeedrunTimer)); - pauseMenu.Add(new Menu.Spacer()); - pauseMenu.Add(new Menu.Slider("BGM", 0, 10, () => Save.Instance.MusicVolume, Save.Instance.SetMusicVolume)); - pauseMenu.Add(new Menu.Slider("SFX", 0, 10, () => Save.Instance.SfxVolume, Save.Instance.SetSfxVolume)); - pauseMenu.Add(new Menu.Spacer()); + })); + + Menu optionsMenu = new Menu(); + optionsMenu.Title = "Options"; + optionsMenu.Add(new Menu.Toggle("Fullscreen", Save.Instance.ToggleFullscreen, () => Save.Instance.Fullscreen)); + optionsMenu.Add(new Menu.Toggle("Z-Guide", Save.Instance.ToggleZGuide, () => Save.Instance.ZGuide)); + optionsMenu.Add(new Menu.Toggle("Timer", Save.Instance.ToggleTimer, () => Save.Instance.SpeedrunTimer)); + optionsMenu.Add(new Menu.Spacer()); + optionsMenu.Add(new Menu.Slider("BGM", 0, 10, () => Save.Instance.MusicVolume, Save.Instance.SetMusicVolume)); + optionsMenu.Add(new Menu.Slider("SFX", 0, 10, () => Save.Instance.SfxVolume, Save.Instance.SetSfxVolume)); + pauseMenu.Add(new Menu.Submenu("Options", pauseMenu, optionsMenu)); + pauseMenu.Add(new Menu.Option("Save & Quit", () => Game.Instance.Goto(new Transition() { Mode = Transition.Modes.Replace, @@ -368,9 +372,10 @@ public override void Update() // unpause else { - if (Controls.Pause.Pressed || Controls.Cancel.Pressed) - { - SetPaused(false); + if (Controls.Pause.Pressed || Controls.Cancel.Pressed && pauseMenu.isInMainMenu()) + { + pauseMenu.closeSubmenus(); + SetPaused(false); Audio.Play(Sfx.ui_unpause); } else From 2749a0fcf6c466e0be3722006ca246447e535617 Mon Sep 17 00:00:00 2001 From: JoshuaMadd Date: Sat, 3 Feb 2024 01:59:52 +0100 Subject: [PATCH 25/27] fix code allignment --- Source/Helpers/Menu.cs | 128 +++++++++++++++++++++-------------------- Source/Scenes/World.cs | 20 +++---- 2 files changed, 75 insertions(+), 73 deletions(-) diff --git a/Source/Helpers/Menu.cs b/Source/Helpers/Menu.cs index 4e771de..30a4ac8 100644 --- a/Source/Helpers/Menu.cs +++ b/Source/Helpers/Menu.cs @@ -13,7 +13,7 @@ public abstract class Item { public virtual string Label { get; } = string.Empty; public virtual bool Selectable { get; } = true; - public virtual bool Pressed() => false; + public virtual bool Pressed() => false; public virtual void Slide(int dir) {} } @@ -21,8 +21,10 @@ public class Submenu(string label, Menu mainMenu, Menu? submenu = null) : Item { private readonly string label = label; public override string Label => label; - public override bool Pressed() { - if (submenu != null) { + public override bool Pressed() + { + if (submenu != null) + { Audio.Play(Sfx.ui_select); mainMenu.Index = 0; mainMenu.Title = submenu.Title; @@ -100,55 +102,55 @@ public int Index set => index = value; } - public string Title { - get => title; - set => title = value; - } + public string Title { + get => title; + set => title = value; + } - public bool Focused = true; + public bool Focused = true; private readonly SpriteFont font; - //Stack to keeps track of all menus before current menu - private readonly Stack> menuStack = new Stack>(); - private int index = 0; + //Stack to keeps track of all menus before current menu + private readonly Stack> menuStack = new Stack>(); + private int index = 0; private string title = string.Empty; public string UpSound = Sfx.ui_move; public string DownSound = Sfx.ui_move; - protected List getCurrentItems() + protected List getCurrentItems() { - return menuStack.Peek(); - } - - protected void addItemsToStack(List items) + return menuStack.Peek(); + } + + protected void addItemsToStack(List items) { - menuStack.Push(items); - } - - public bool isInMainMenu() + menuStack.Push(items); + } + + public bool isInMainMenu() { - return menuStack.Count == 1; - } - - public void closeSubmenus() + return menuStack.Count == 1; + } + + public void closeSubmenus() { - while (menuStack.Count > 1) { menuStack.Pop(); } - } - - public Vec2 Size + while (menuStack.Count > 1) { menuStack.Pop(); } + } + + public Vec2 Size { get { Vec2 size = Vec2.Zero; - + if (!string.IsNullOrEmpty(title)) { - size.X = font.WidthOf(title); - size.Y += font.LineHeight; + size.X = font.WidthOf(title); + size.Y += font.LineHeight; size.Y += SpacerHeight + Spacing; - } - - foreach (var item in getCurrentItems()) + } + + foreach (var item in getCurrentItems()) { if (string.IsNullOrEmpty(item.Label)) { @@ -161,26 +163,26 @@ public Vec2 Size } size.Y += Spacing; } - + if (getCurrentItems().Count > 0) size.Y -= Spacing; - + return size; } } - + public Menu() { font = Assets.Fonts.First().Value; menuStack.Push(new List()); } - + public Menu Add(Item item) { - getCurrentItems().Add(item); + getCurrentItems().Add(item); return this; } - + public void Update() { if (getCurrentItems().Count > 0 && Focused) @@ -191,49 +193,49 @@ public void Update() step = 1; if (Controls.Menu.Vertical.Negative.Pressed) step = -1; - + index += step; while (!getCurrentItems()[(getCurrentItems().Count + index) % getCurrentItems().Count].Selectable) index += step; index = (getCurrentItems().Count + index) % getCurrentItems().Count; - + if (was != index) Audio.Play(step < 0 ? UpSound : DownSound); - + if (Controls.Menu.Horizontal.Negative.Pressed) - getCurrentItems()[index].Slide(-1); + getCurrentItems()[index].Slide(-1); if (Controls.Menu.Horizontal.Positive.Pressed) - getCurrentItems()[index].Slide(1); - + getCurrentItems()[index].Slide(1); + if (Controls.Confirm.Pressed && getCurrentItems()[index].Pressed()) Controls.Consume(); - if (Controls.Cancel.Pressed && !isInMainMenu()) + if (Controls.Cancel.Pressed && !isInMainMenu()) { - Audio.Play(Sfx.main_menu_toggle_off); + Audio.Play(Sfx.main_menu_toggle_off); Index = 0; menuStack.Pop(); } - } + } } - + public void Render(Batcher batch, Vec2 position) { var size = Size; batch.PushMatrix(-size / 2); - + if(!string.IsNullOrEmpty(title)) { - var at = position + new Vec2(size.X / 2, 0); - var text = title; - var justify = new Vec2(0.5f, 0); - var color = new Color(8421504); - - UI.Text(batch, text, at, justify, color); + var at = position + new Vec2(size.X / 2, 0); + var text = title; + var justify = new Vec2(0.5f, 0); + var color = new Color(8421504); - position.Y += font.LineHeight; - position.Y += SpacerHeight + Spacing; - } + UI.Text(batch, text, at, justify, color); + position.Y += font.LineHeight; + position.Y += SpacerHeight + Spacing; + } + for (int i = 0; i < getCurrentItems().Count; i ++) { if (string.IsNullOrEmpty(getCurrentItems()[i].Label)) @@ -241,17 +243,17 @@ public void Render(Batcher batch, Vec2 position) position.Y += SpacerHeight; continue; } - + var at = position + new Vec2(size.X / 2, 0); var text = getCurrentItems()[i].Label; var justify = new Vec2(0.5f, 0); var color = index == i && Focused ? (Time.BetweenInterval(0.1f) ? 0x84FF54 : 0xFCFF59) : Color.White; UI.Text(batch, text, at, justify, color); - + position.Y += font.LineHeight; position.Y += Spacing; - } + } batch.PopMatrix(); } } \ No newline at end of file diff --git a/Source/Scenes/World.cs b/Source/Scenes/World.cs index d37b692..60222b4 100644 --- a/Source/Scenes/World.cs +++ b/Source/Scenes/World.cs @@ -86,15 +86,15 @@ public World(EntryInfo entry) Get()?.Kill(); })); - Menu optionsMenu = new Menu(); + Menu optionsMenu = new Menu(); optionsMenu.Title = "Options"; - optionsMenu.Add(new Menu.Toggle("Fullscreen", Save.Instance.ToggleFullscreen, () => Save.Instance.Fullscreen)); - optionsMenu.Add(new Menu.Toggle("Z-Guide", Save.Instance.ToggleZGuide, () => Save.Instance.ZGuide)); - optionsMenu.Add(new Menu.Toggle("Timer", Save.Instance.ToggleTimer, () => Save.Instance.SpeedrunTimer)); - optionsMenu.Add(new Menu.Spacer()); - optionsMenu.Add(new Menu.Slider("BGM", 0, 10, () => Save.Instance.MusicVolume, Save.Instance.SetMusicVolume)); - optionsMenu.Add(new Menu.Slider("SFX", 0, 10, () => Save.Instance.SfxVolume, Save.Instance.SetSfxVolume)); - pauseMenu.Add(new Menu.Submenu("Options", pauseMenu, optionsMenu)); + optionsMenu.Add(new Menu.Toggle("Fullscreen", Save.Instance.ToggleFullscreen, () => Save.Instance.Fullscreen)); + optionsMenu.Add(new Menu.Toggle("Z-Guide", Save.Instance.ToggleZGuide, () => Save.Instance.ZGuide)); + optionsMenu.Add(new Menu.Toggle("Timer", Save.Instance.ToggleTimer, () => Save.Instance.SpeedrunTimer)); + optionsMenu.Add(new Menu.Spacer()); + optionsMenu.Add(new Menu.Slider("BGM", 0, 10, () => Save.Instance.MusicVolume, Save.Instance.SetMusicVolume)); + optionsMenu.Add(new Menu.Slider("SFX", 0, 10, () => Save.Instance.SfxVolume, Save.Instance.SetSfxVolume)); + pauseMenu.Add(new Menu.Submenu("Options", pauseMenu, optionsMenu)); pauseMenu.Add(new Menu.Option("Save & Quit", () => Game.Instance.Goto(new Transition() { @@ -374,8 +374,8 @@ public override void Update() { if (Controls.Pause.Pressed || Controls.Cancel.Pressed && pauseMenu.isInMainMenu()) { - pauseMenu.closeSubmenus(); - SetPaused(false); + pauseMenu.closeSubmenus(); + SetPaused(false); Audio.Play(Sfx.ui_unpause); } else From 8f459c4da60b4bfe3204469e89b8950bb1c06dde Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Sat, 3 Feb 2024 12:24:05 -0800 Subject: [PATCH 26/27] some submenu organization/cleanup --- Source/Helpers/Menu.cs | 124 ++++++++++++++++++++--------------------- Source/Scenes/World.cs | 37 ++++++------ 2 files changed, 78 insertions(+), 83 deletions(-) diff --git a/Source/Helpers/Menu.cs b/Source/Helpers/Menu.cs index 30a4ac8..94ae5b7 100644 --- a/Source/Helpers/Menu.cs +++ b/Source/Helpers/Menu.cs @@ -8,6 +8,7 @@ public class Menu { public const float Spacing = 4 * Game.RelativeScale; public const float SpacerHeight = 12 * Game.RelativeScale; + public const float TitleScale = 0.75f; public abstract class Item { @@ -17,7 +18,7 @@ public abstract class Item public virtual void Slide(int dir) {} } - public class Submenu(string label, Menu mainMenu, Menu? submenu = null) : Item + public class Submenu(string label, Menu? rootMenu, Menu? submenu = null) : Item { private readonly string label = label; public override string Label => label; @@ -26,11 +27,11 @@ public override bool Pressed() if (submenu != null) { Audio.Play(Sfx.ui_select); - mainMenu.Index = 0; - mainMenu.Title = submenu.Title; - mainMenu.addItemsToStack(submenu.getCurrentItems()); + submenu.Index = 0; + rootMenu?.PushSubMenu(submenu); return true; } + return false; } } @@ -96,46 +97,25 @@ public override bool Pressed() } } - public int Index - { - get => index; - set => index = value; - } - - public string Title { - get => title; - set => title = value; - } - + public int Index; + public string Title = string.Empty; public bool Focused = true; private readonly SpriteFont font; - //Stack to keeps track of all menus before current menu - private readonly Stack> menuStack = new Stack>(); - private int index = 0; - private string title = string.Empty; + private readonly List items = []; + private readonly Stack submenus = []; public string UpSound = Sfx.ui_move; public string DownSound = Sfx.ui_move; - protected List getCurrentItems() - { - return menuStack.Peek(); - } - - protected void addItemsToStack(List items) - { - menuStack.Push(items); - } - - public bool isInMainMenu() - { - return menuStack.Count == 1; - } - - public void closeSubmenus() + public bool IsInMainMenu => submenus.Count <= 0; + private Menu CurrentMenu => submenus.Count > 0 ? submenus.Peek() : this; + private string CurrentTitle => CurrentMenu.Title; + private List CurrentItems => CurrentMenu.items; + private int CurrentIndex { - while (menuStack.Count > 1) { menuStack.Pop(); } + get => CurrentMenu.Index; + set => CurrentMenu.Index = value; } public Vec2 Size @@ -144,13 +124,14 @@ public Vec2 Size { Vec2 size = Vec2.Zero; - if (!string.IsNullOrEmpty(title)) { - size.X = font.WidthOf(title); - size.Y += font.LineHeight; + if (!string.IsNullOrEmpty(Title)) + { + size.X = font.WidthOf(Title) * TitleScale; + size.Y += font.LineHeight * TitleScale; size.Y += SpacerHeight + Spacing; } - foreach (var item in getCurrentItems()) + foreach (var item in CurrentItems) { if (string.IsNullOrEmpty(item.Label)) { @@ -164,7 +145,7 @@ public Vec2 Size size.Y += Spacing; } - if (getCurrentItems().Count > 0) + if (CurrentItems.Count > 0) size.Y -= Spacing; return size; @@ -174,46 +155,57 @@ public Vec2 Size public Menu() { font = Assets.Fonts.First().Value; - menuStack.Push(new List()); } public Menu Add(Item item) { - getCurrentItems().Add(item); + items.Add(item); return this; } + protected void PushSubMenu(Menu menu) + { + submenus.Push(menu); + } + + public void CloseSubMenus() + { + while (submenus.Count > 0) + submenus.Pop(); + } + public void Update() { - if (getCurrentItems().Count > 0 && Focused) + if (CurrentItems.Count > 0 && Focused) { - var was = index; + var was = CurrentIndex; var step = 0; + if (Controls.Menu.Vertical.Positive.Pressed) step = 1; if (Controls.Menu.Vertical.Negative.Pressed) step = -1; - index += step; - while (!getCurrentItems()[(getCurrentItems().Count + index) % getCurrentItems().Count].Selectable) - index += step; - index = (getCurrentItems().Count + index) % getCurrentItems().Count; + CurrentIndex += step; + while (!CurrentItems[(CurrentItems.Count + CurrentIndex) % CurrentItems.Count].Selectable) + CurrentIndex += step; + CurrentIndex = (CurrentItems.Count + CurrentIndex) % CurrentItems.Count; - if (was != index) + if (was != CurrentIndex) Audio.Play(step < 0 ? UpSound : DownSound); if (Controls.Menu.Horizontal.Negative.Pressed) - getCurrentItems()[index].Slide(-1); + CurrentItems[CurrentIndex].Slide(-1); if (Controls.Menu.Horizontal.Positive.Pressed) - getCurrentItems()[index].Slide(1); + CurrentItems[CurrentIndex].Slide(1); - if (Controls.Confirm.Pressed && getCurrentItems()[index].Pressed()) + if (Controls.Confirm.Pressed && CurrentItems[CurrentIndex].Pressed()) Controls.Consume(); - if (Controls.Cancel.Pressed && !isInMainMenu()) + + if (Controls.Cancel.Pressed && !IsInMainMenu) { Audio.Play(Sfx.main_menu_toggle_off); - Index = 0; - menuStack.Pop(); + submenus.Pop(); } } } @@ -223,31 +215,35 @@ public void Render(Batcher batch, Vec2 position) var size = Size; batch.PushMatrix(-size / 2); - if(!string.IsNullOrEmpty(title)) + if(!string.IsNullOrEmpty(CurrentTitle)) { var at = position + new Vec2(size.X / 2, 0); - var text = title; + var text = CurrentTitle; var justify = new Vec2(0.5f, 0); var color = new Color(8421504); - UI.Text(batch, text, at, justify, color); + batch.PushMatrix( + Matrix3x2.CreateScale(TitleScale) * + Matrix3x2.CreateTranslation(at)); + UI.Text(batch, text, Vec2.Zero, justify, color); + batch.PopMatrix(); - position.Y += font.LineHeight; + position.Y += font.LineHeight * TitleScale; position.Y += SpacerHeight + Spacing; } - for (int i = 0; i < getCurrentItems().Count; i ++) + for (int i = 0; i < CurrentItems.Count; i ++) { - if (string.IsNullOrEmpty(getCurrentItems()[i].Label)) + if (string.IsNullOrEmpty(CurrentItems[i].Label)) { position.Y += SpacerHeight; continue; } var at = position + new Vec2(size.X / 2, 0); - var text = getCurrentItems()[i].Label; + var text = CurrentItems[i].Label; var justify = new Vec2(0.5f, 0); - var color = index == i && Focused ? (Time.BetweenInterval(0.1f) ? 0x84FF54 : 0xFCFF59) : Color.White; + var color = CurrentIndex == i && Focused ? (Time.BetweenInterval(0.1f) ? 0x84FF54 : 0xFCFF59) : Color.White; UI.Text(batch, text, at, justify, color); diff --git a/Source/Scenes/World.cs b/Source/Scenes/World.cs index 60222b4..604c8b5 100644 --- a/Source/Scenes/World.cs +++ b/Source/Scenes/World.cs @@ -76,26 +76,25 @@ public World(EntryInfo entry) strawbCounterWiggle = 0; // setup pause menu - { - pauseMenu.Title = "Paused"; + { + Menu optionsMenu = new Menu(); + optionsMenu.Title = "Options"; + optionsMenu.Add(new Menu.Toggle("Fullscreen", Save.Instance.ToggleFullscreen, () => Save.Instance.Fullscreen)); + optionsMenu.Add(new Menu.Toggle("Z-Guide", Save.Instance.ToggleZGuide, () => Save.Instance.ZGuide)); + optionsMenu.Add(new Menu.Toggle("Timer", Save.Instance.ToggleTimer, () => Save.Instance.SpeedrunTimer)); + optionsMenu.Add(new Menu.Spacer()); + optionsMenu.Add(new Menu.Slider("BGM", 0, 10, () => Save.Instance.MusicVolume, Save.Instance.SetMusicVolume)); + optionsMenu.Add(new Menu.Slider("SFX", 0, 10, () => Save.Instance.SfxVolume, Save.Instance.SetSfxVolume)); + + pauseMenu.Title = "Paused"; pauseMenu.Add(new Menu.Option("Resume", () => SetPaused(false))); pauseMenu.Add(new Menu.Option("Retry", () => { SetPaused(false); Audio.StopBus(Sfx.bus_dialog, false); Get()?.Kill(); - })); - - Menu optionsMenu = new Menu(); - optionsMenu.Title = "Options"; - optionsMenu.Add(new Menu.Toggle("Fullscreen", Save.Instance.ToggleFullscreen, () => Save.Instance.Fullscreen)); - optionsMenu.Add(new Menu.Toggle("Z-Guide", Save.Instance.ToggleZGuide, () => Save.Instance.ZGuide)); - optionsMenu.Add(new Menu.Toggle("Timer", Save.Instance.ToggleTimer, () => Save.Instance.SpeedrunTimer)); - optionsMenu.Add(new Menu.Spacer()); - optionsMenu.Add(new Menu.Slider("BGM", 0, 10, () => Save.Instance.MusicVolume, Save.Instance.SetMusicVolume)); - optionsMenu.Add(new Menu.Slider("SFX", 0, 10, () => Save.Instance.SfxVolume, Save.Instance.SetSfxVolume)); + })); pauseMenu.Add(new Menu.Submenu("Options", pauseMenu, optionsMenu)); - pauseMenu.Add(new Menu.Option("Save & Quit", () => Game.Instance.Goto(new Transition() { Mode = Transition.Modes.Replace, @@ -372,9 +371,9 @@ public override void Update() // unpause else { - if (Controls.Pause.Pressed || Controls.Cancel.Pressed && pauseMenu.isInMainMenu()) - { - pauseMenu.closeSubmenus(); + if ((Controls.Pause.Pressed || Controls.Cancel.Pressed) && pauseMenu.IsInMainMenu) + { + pauseMenu.CloseSubMenus(); SetPaused(false); Audio.Play(Sfx.ui_unpause); } @@ -801,9 +800,9 @@ public override void Render(Target target) } // show version number when paused / in ending area - if (IsInEndingArea || Paused) - { - UI.Text(batch, Game.VersionString, bounds.BottomLeft + new Vec2(4, -4) * Game.RelativeScale, new Vec2(0, 1), Color.White * 0.25f); + if (IsInEndingArea || Paused) + { + UI.Text(batch, Game.VersionString, bounds.BottomLeft + new Vec2(4, -4) * Game.RelativeScale, new Vec2(0, 1), Color.White * 0.25f); } } From c2e8651ad3da6e8e157377e6d980031454b9acea Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Sat, 3 Feb 2024 12:31:23 -0800 Subject: [PATCH 27/27] simplifying submenu code a bit --- Source/Helpers/Menu.cs | 73 ++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/Source/Helpers/Menu.cs b/Source/Helpers/Menu.cs index 94ae5b7..42c16f0 100644 --- a/Source/Helpers/Menu.cs +++ b/Source/Helpers/Menu.cs @@ -1,7 +1,4 @@ -using System.Reflection.Emit; -using static Celeste64.Menu; - namespace Celeste64; public class Menu @@ -110,13 +107,6 @@ public override bool Pressed() public bool IsInMainMenu => submenus.Count <= 0; private Menu CurrentMenu => submenus.Count > 0 ? submenus.Peek() : this; - private string CurrentTitle => CurrentMenu.Title; - private List CurrentItems => CurrentMenu.items; - private int CurrentIndex - { - get => CurrentMenu.Index; - set => CurrentMenu.Index = value; - } public Vec2 Size { @@ -131,7 +121,7 @@ public Vec2 Size size.Y += SpacerHeight + Spacing; } - foreach (var item in CurrentItems) + foreach (var item in items) { if (string.IsNullOrEmpty(item.Label)) { @@ -145,7 +135,7 @@ public Vec2 Size size.Y += Spacing; } - if (CurrentItems.Count > 0) + if (items.Count > 0) size.Y -= Spacing; return size; @@ -170,15 +160,14 @@ protected void PushSubMenu(Menu menu) public void CloseSubMenus() { - while (submenus.Count > 0) - submenus.Pop(); + submenus.Clear(); } - - public void Update() + + private void HandleInput() { - if (CurrentItems.Count > 0 && Focused) + if (items.Count > 0) { - var was = CurrentIndex; + var was = Index; var step = 0; if (Controls.Menu.Vertical.Positive.Pressed) @@ -186,21 +175,29 @@ public void Update() if (Controls.Menu.Vertical.Negative.Pressed) step = -1; - CurrentIndex += step; - while (!CurrentItems[(CurrentItems.Count + CurrentIndex) % CurrentItems.Count].Selectable) - CurrentIndex += step; - CurrentIndex = (CurrentItems.Count + CurrentIndex) % CurrentItems.Count; + Index += step; + while (!items[(items.Count + Index) % items.Count].Selectable) + Index += step; + Index = (items.Count + Index) % items.Count; - if (was != CurrentIndex) + if (was != Index) Audio.Play(step < 0 ? UpSound : DownSound); if (Controls.Menu.Horizontal.Negative.Pressed) - CurrentItems[CurrentIndex].Slide(-1); + items[Index].Slide(-1); if (Controls.Menu.Horizontal.Positive.Pressed) - CurrentItems[CurrentIndex].Slide(1); + items[Index].Slide(1); - if (Controls.Confirm.Pressed && CurrentItems[CurrentIndex].Pressed()) + if (Controls.Confirm.Pressed && items[Index].Pressed()) Controls.Consume(); + } + } + + public void Update() + { + if (Focused) + { + CurrentMenu.HandleInput(); if (Controls.Cancel.Pressed && !IsInMainMenu) { @@ -209,16 +206,17 @@ public void Update() } } } - - public void Render(Batcher batch, Vec2 position) + + private void RenderItems(Batcher batch) { var size = Size; + var position = Vec2.Zero; batch.PushMatrix(-size / 2); - if(!string.IsNullOrEmpty(CurrentTitle)) + if(!string.IsNullOrEmpty(Title)) { var at = position + new Vec2(size.X / 2, 0); - var text = CurrentTitle; + var text = Title; var justify = new Vec2(0.5f, 0); var color = new Color(8421504); @@ -232,18 +230,18 @@ public void Render(Batcher batch, Vec2 position) position.Y += SpacerHeight + Spacing; } - for (int i = 0; i < CurrentItems.Count; i ++) + for (int i = 0; i < items.Count; i ++) { - if (string.IsNullOrEmpty(CurrentItems[i].Label)) + if (string.IsNullOrEmpty(items[i].Label)) { position.Y += SpacerHeight; continue; } var at = position + new Vec2(size.X / 2, 0); - var text = CurrentItems[i].Label; + var text = items[i].Label; var justify = new Vec2(0.5f, 0); - var color = CurrentIndex == i && Focused ? (Time.BetweenInterval(0.1f) ? 0x84FF54 : 0xFCFF59) : Color.White; + var color = Index == i && Focused ? (Time.BetweenInterval(0.1f) ? 0x84FF54 : 0xFCFF59) : Color.White; UI.Text(batch, text, at, justify, color); @@ -252,4 +250,11 @@ public void Render(Batcher batch, Vec2 position) } batch.PopMatrix(); } + + public void Render(Batcher batch, Vec2 position) + { + batch.PushMatrix(position); + CurrentMenu.RenderItems(batch); + batch.PopMatrix(); + } } \ No newline at end of file