diff --git a/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Resources/AddonSaverSettings.json b/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Resources/AddonSaverSettings.json
index c1ed42115..35022712b 100644
--- a/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Resources/AddonSaverSettings.json
+++ b/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Resources/AddonSaverSettings.json
@@ -7324,5 +7324,100 @@
]
}
]
+ },
+ {
+ "Name": "PointTrack",
+ "Desc": "Block moving in a wave pattern with green rulers tracking its position.",
+ "Keys": [
+ {
+ "Name": "Delay in Milliseconds",
+ "Type": "SInt",
+ "Variable": "PointTrackDelay",
+ "Description": "How many milliseconds to wait before making the next write?"
+ },
+ {
+ "Name": "Horizontal Frequency Level",
+ "Type": "SDouble",
+ "Variable": "PointTrackHorizontalFrequencyLevel",
+ "Description": "The level of the horizontal frequency. This is the denominator of the Pi value in mathematics. Use this to create beautiful wavy swivels!"
+ },
+ {
+ "Name": "Vertical Frequency Level",
+ "Type": "SDouble",
+ "Variable": "PointTrackVerticalFrequencyLevel",
+ "Description": "The level of the vertical frequency. This is the denominator of the Pi value in mathematics. Use this to create beautiful wavy swivels!"
+ },
+ {
+ "Name": "Color settings",
+ "Type": "SMultivar",
+ "Description": "This allows you to configure the colors",
+ "Variables": [
+ {
+ "Name": "Minimum red color level",
+ "Type": "SIntSlider",
+ "Variable": "PointTrackMinimumRedColorLevel",
+ "Description": "Minimum red color level. The minimum accepted value is 0 and the maximum accepted value is 255.",
+ "MinimumValue": 0,
+ "MaximumValue": 255
+ },
+ {
+ "Name": "Minimum green color level",
+ "Type": "SIntSlider",
+ "Variable": "PointTrackMinimumGreenColorLevel",
+ "Description": "Minimum green color level. The minimum accepted value is 0 and the maximum accepted value is 255.",
+ "MinimumValue": 0,
+ "MaximumValue": 255
+ },
+ {
+ "Name": "Minimum blue color level",
+ "Type": "SIntSlider",
+ "Variable": "PointTrackMinimumBlueColorLevel",
+ "Description": "Minimum blue color level. The minimum accepted value is 0 and the maximum accepted value is 255.",
+ "MinimumValue": 0,
+ "MaximumValue": 255
+ },
+ {
+ "Name": "Minimum color level",
+ "Type": "SIntSlider",
+ "Variable": "PointTrackMinimumColorLevel",
+ "Description": "Minimum color level. The minimum accepted value is 0 and the maximum accepted value is 255 for 255 colors or 16 for 16 colors.",
+ "MinimumValue": 0,
+ "MaximumValue": 255
+ },
+ {
+ "Name": "Maximum red color level",
+ "Type": "SIntSlider",
+ "Variable": "PointTrackMaximumRedColorLevel",
+ "Description": "Maximum red color level. The minimum accepted value is 0 and the maximum accepted value is 255.",
+ "MinimumValue": 0,
+ "MaximumValue": 255
+ },
+ {
+ "Name": "Maximum green color level",
+ "Type": "SIntSlider",
+ "Variable": "PointTrackMaximumGreenColorLevel",
+ "Description": "Maximum green color level. The minimum accepted value is 0 and the maximum accepted value is 255.",
+ "MinimumValue": 0,
+ "MaximumValue": 255
+ },
+ {
+ "Name": "Maximum blue color level",
+ "Type": "SIntSlider",
+ "Variable": "PointTrackMaximumBlueColorLevel",
+ "Description": "Maximum blue color level. The minimum accepted value is 0 and the maximum accepted value is 255.",
+ "MinimumValue": 0,
+ "MaximumValue": 255
+ },
+ {
+ "Name": "Maximum color level",
+ "Type": "SIntSlider",
+ "Variable": "PointTrackMaximumColorLevel",
+ "Description": "Maximum color level. The minimum accepted value is 0 and the maximum accepted value is 255 for 255 colors or 16 for 16 colors.",
+ "MinimumValue": 0,
+ "MaximumValue": 255
+ }
+ ]
+ }
+ ]
}
]
diff --git a/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/ScreensaverPackInit.cs b/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/ScreensaverPackInit.cs
index 0a82a9171..31ac7392c 100644
--- a/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/ScreensaverPackInit.cs
+++ b/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/ScreensaverPackInit.cs
@@ -98,6 +98,7 @@ internal class ScreensaverPackInit : IAddon
{ "numberscatter", new NumberScatterDisplay() },
{ "omen", new OmenDisplay() },
{ "particles", new ParticlesDisplay() },
+ { "pointtrack", new PointTrackDisplay() },
{ "progressclock", new ProgressClockDisplay() },
{ "pulse", new PulseDisplay() },
{ "ramp", new RampDisplay() },
diff --git a/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Screensavers/PointTrack.cs b/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Screensavers/PointTrack.cs
new file mode 100644
index 000000000..5c3b6ceff
--- /dev/null
+++ b/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Screensavers/PointTrack.cs
@@ -0,0 +1,172 @@
+//
+// Nitrocid KS Copyright (C) 2018-2025 Aptivi
+//
+// This file is part of Nitrocid KS
+//
+// Nitrocid KS is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Nitrocid KS is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY, without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Terminaux.Writer.ConsoleWriters;
+using Nitrocid.Drivers.RNG;
+using Nitrocid.Kernel.Debugging;
+using Nitrocid.Misc.Screensaver;
+using Nitrocid.Kernel.Configuration;
+using Terminaux.Colors;
+using Terminaux.Base;
+using Terminaux.Colors.Data;
+using System.Text;
+using Terminaux.Writer.CyclicWriters;
+
+namespace Nitrocid.ScreensaverPacks.Screensavers
+{
+ ///
+ /// Display for PointTrack
+ ///
+ public class PointTrackDisplay : BaseScreensaver, IScreensaver
+ {
+ private Color targetColor = ConsoleColors.Lime;
+ private int posIdxVertical = 0;
+ private int posIdxHorizontal = 0;
+
+ ///
+ public override string ScreensaverName =>
+ "PointTrack";
+
+ ///
+ public override void ScreensaverPreparation()
+ {
+ posIdxVertical = 0;
+ posIdxHorizontal = 0;
+
+ // Make an initial color storage
+ int RedColorNum = RandomDriver.Random(ScreensaverPackInit.SaversConfig.TrailsMinimumRedColorLevel, ScreensaverPackInit.SaversConfig.TrailsMaximumRedColorLevel);
+ int GreenColorNum = RandomDriver.Random(ScreensaverPackInit.SaversConfig.TrailsMinimumGreenColorLevel, ScreensaverPackInit.SaversConfig.TrailsMaximumGreenColorLevel);
+ int BlueColorNum = RandomDriver.Random(ScreensaverPackInit.SaversConfig.TrailsMinimumBlueColorLevel, ScreensaverPackInit.SaversConfig.TrailsMaximumBlueColorLevel);
+ targetColor = new(RedColorNum, GreenColorNum, BlueColorNum);
+ DebugWriter.WriteDebugConditional(Config.MainConfig.ScreensaverDebug, DebugLevel.I, "Got color (R;G;B: {0};{1};{2})", RedColorNum, GreenColorNum, BlueColorNum);
+ }
+
+ ///
+ public override void ScreensaverLogic()
+ {
+ ConsoleWrapper.CursorVisible = false;
+ ColorTools.LoadBack();
+
+ // First, prepare how many dots to render according to the console size
+ int Height = ConsoleWrapper.WindowHeight - 4;
+ int Width = ConsoleWrapper.WindowWidth - 4;
+
+ // Then, go ahead and make these bars swivel themselves.
+ List CurrentPosVertical = [];
+ List CurrentPosHorizontal = [];
+ double FrequencyVertical = Math.PI / ScreensaverPackInit.SaversConfig.PointTrackVerticalFrequencyLevel;
+ double FrequencyHorizontal = Math.PI / ScreensaverPackInit.SaversConfig.PointTrackHorizontalFrequencyLevel;
+
+ // Set the current vertical positions
+ double TimeSecsVertical = 0.0;
+ bool isSetVertical = false;
+ while (true)
+ {
+ TimeSecsVertical += 0.1;
+ double calculatedHeight = Height * Math.Cos(FrequencyVertical * TimeSecsVertical) / 2;
+ CurrentPosVertical.Add((int)calculatedHeight);
+ if ((int)calculatedHeight == Height / 2 && isSetVertical)
+ break;
+ if (!isSetVertical && (int)calculatedHeight < Height / 2)
+ isSetVertical = true;
+ }
+
+ // Set the current horizontal positions
+ double TimeSecsHorizontal = 0.0;
+ bool isSetHorizontal = false;
+ while (true)
+ {
+ TimeSecsHorizontal += 0.1;
+ double calculatedWidth = Width * Math.Cos(FrequencyHorizontal * TimeSecsHorizontal) / 2;
+ CurrentPosHorizontal.Add((int)calculatedWidth);
+ if ((int)calculatedWidth == Width / 2 && isSetHorizontal)
+ break;
+ if (!isSetHorizontal && (int)calculatedWidth < Width / 2)
+ isSetHorizontal = true;
+ }
+
+ // Render the block and the position rulers
+ posIdxVertical++;
+ if (posIdxVertical >= CurrentPosVertical.Count)
+ posIdxVertical = 0;
+ posIdxHorizontal++;
+ if (posIdxHorizontal >= CurrentPosHorizontal.Count)
+ posIdxHorizontal = 0;
+ int PosVertical = CurrentPosVertical[posIdxVertical] + Math.Abs(CurrentPosVertical.Min()) + 2;
+ int PosHorizontal = CurrentPosHorizontal[posIdxHorizontal] + Math.Abs(CurrentPosHorizontal.Min()) + 2;
+ if (!ConsoleResizeHandler.WasResized(false))
+ {
+ // Render the block
+ TextWriterWhereColor.WriteWhereColorBack(" ", PosHorizontal, PosVertical, Color.Empty, targetColor);
+
+ // Now, make the position ruler writers
+ var lineBuilder = new StringBuilder();
+ var topRuler = new Line()
+ {
+ DoubleWidth = false,
+ StartPos = new(PosHorizontal, 0),
+ EndPos = new(PosHorizontal, PosVertical - 4),
+ Color = ConsoleColors.Lime,
+ };
+ var bottomRuler = new Line()
+ {
+ DoubleWidth = false,
+ StartPos = new(PosHorizontal, PosVertical + 2),
+ EndPos = new(PosHorizontal, ConsoleWrapper.WindowHeight - 1),
+ Color = ConsoleColors.Lime,
+ };
+ var leftRuler = new Line()
+ {
+ DoubleWidth = false,
+ StartPos = new(0, PosVertical - 1),
+ EndPos = new(PosHorizontal - 4, PosVertical - 1),
+ Color = ConsoleColors.Lime,
+ };
+ var rightRuler = new Line()
+ {
+ DoubleWidth = false,
+ StartPos = new(PosHorizontal + 4, PosVertical - 1),
+ EndPos = new(ConsoleWrapper.WindowWidth - 1, PosVertical - 1),
+ Color = ConsoleColors.Lime,
+ };
+
+ // Check the ruler states
+ if (topRuler.EndPos.Y >= topRuler.StartPos.Y)
+ lineBuilder.Append(topRuler.Render());
+ if (bottomRuler.EndPos.Y >= bottomRuler.StartPos.Y)
+ lineBuilder.Append(bottomRuler.Render());
+ if (leftRuler.EndPos.X >= leftRuler.StartPos.X)
+ lineBuilder.Append(leftRuler.Render());
+ if (rightRuler.EndPos.X >= rightRuler.StartPos.X)
+ lineBuilder.Append(rightRuler.Render());
+
+ // Render the bars
+ TextWriterRaw.WriteRaw(lineBuilder.ToString());
+ }
+
+ // Reset resize sync
+ ConsoleResizeHandler.WasResized();
+ ScreensaverManager.Delay(ScreensaverPackInit.SaversConfig.PointTrackDelay);
+ }
+
+ }
+}
diff --git a/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Screensavers/Trails.cs b/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Screensavers/Trails.cs
index f9f0c41d4..e9873a972 100644
--- a/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Screensavers/Trails.cs
+++ b/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Screensavers/Trails.cs
@@ -71,7 +71,7 @@ public override void ScreensaverLogic()
int Height = ConsoleWrapper.WindowHeight - 4;
int Width = ConsoleWrapper.WindowWidth - 4;
- // Then, go ahead and make these bars trails themselves.
+ // Then, go ahead and make these bars swivel themselves.
List CurrentPosVertical = [];
List CurrentPosHorizontal = [];
double FrequencyVertical = Math.PI / ScreensaverPackInit.SaversConfig.TrailsVerticalFrequencyLevel;
diff --git a/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Settings/ExtraSaversConfig.cs b/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Settings/ExtraSaversConfig.cs
index cb9b248e7..53b9e1da4 100644
--- a/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Settings/ExtraSaversConfig.cs
+++ b/public/Nitrocid.Addons/Nitrocid.ScreensaverPacks/Settings/ExtraSaversConfig.cs
@@ -15198,5 +15198,214 @@ public int TrailsMaximumColorLevel
}
}
#endregion
+
+ #region PointTrack
+ private int pointTrackDelay = 100;
+ private double pointTrackHorizontalFrequencyLevel = 3;
+ private double pointTrackVerticalFrequencyLevel = 8;
+ private int pointTrackMinimumRedColorLevel = 0;
+ private int pointTrackMinimumGreenColorLevel = 0;
+ private int pointTrackMinimumBlueColorLevel = 0;
+ private int pointTrackMinimumColorLevel = 0;
+ private int pointTrackMaximumRedColorLevel = 255;
+ private int pointTrackMaximumGreenColorLevel = 255;
+ private int pointTrackMaximumBlueColorLevel = 255;
+ private int pointTrackMaximumColorLevel = 255;
+
+ ///
+ /// [PointTrack] How many milliseconds to wait before making the next write?
+ ///
+ public int PointTrackDelay
+ {
+ get
+ {
+ return pointTrackDelay;
+ }
+ set
+ {
+ if (value <= 0)
+ value = 100;
+ pointTrackDelay = value;
+ }
+ }
+ ///
+ /// [PointTrack] The level of the horizontal frequency. This is the denominator of the Pi value (3.1415926...) in mathematics, defined by . Use this to create beautiful wavy swivels!
+ ///
+ public double PointTrackHorizontalFrequencyLevel
+ {
+ get
+ {
+ return pointTrackHorizontalFrequencyLevel;
+ }
+ set
+ {
+ if (value <= 0)
+ value = 3;
+ pointTrackHorizontalFrequencyLevel = value;
+ }
+ }
+ ///
+ /// [PointTrack] The level of the vertical frequency. This is the denominator of the Pi value (3.1415926...) in mathematics, defined by . Use this to create beautiful wavy swivels!
+ ///
+ public double PointTrackVerticalFrequencyLevel
+ {
+ get
+ {
+ return pointTrackVerticalFrequencyLevel;
+ }
+ set
+ {
+ if (value <= 0)
+ value = 8;
+ pointTrackVerticalFrequencyLevel = value;
+ }
+ }
+ ///
+ /// [PointTrack] The minimum red color level (true color)
+ ///
+ public int PointTrackMinimumRedColorLevel
+ {
+ get
+ {
+ return pointTrackMinimumRedColorLevel;
+ }
+ set
+ {
+ if (value <= 0)
+ value = 0;
+ if (value > 255)
+ value = 255;
+ pointTrackMinimumRedColorLevel = value;
+ }
+ }
+ ///
+ /// [PointTrack] The minimum green color level (true color)
+ ///
+ public int PointTrackMinimumGreenColorLevel
+ {
+ get
+ {
+ return pointTrackMinimumGreenColorLevel;
+ }
+ set
+ {
+ if (value <= 0)
+ value = 0;
+ if (value > 255)
+ value = 255;
+ pointTrackMinimumGreenColorLevel = value;
+ }
+ }
+ ///
+ /// [PointTrack] The minimum blue color level (true color)
+ ///
+ public int PointTrackMinimumBlueColorLevel
+ {
+ get
+ {
+ return pointTrackMinimumBlueColorLevel;
+ }
+ set
+ {
+ if (value <= 0)
+ value = 0;
+ if (value > 255)
+ value = 255;
+ pointTrackMinimumBlueColorLevel = value;
+ }
+ }
+ ///
+ /// [PointTrack] The minimum color level (255 colors or 16 colors)
+ ///
+ public int PointTrackMinimumColorLevel
+ {
+ get
+ {
+ return pointTrackMinimumColorLevel;
+ }
+ set
+ {
+ int FinalMinimumLevel = 255;
+ if (value <= 0)
+ value = 0;
+ if (value > FinalMinimumLevel)
+ value = FinalMinimumLevel;
+ pointTrackMinimumColorLevel = value;
+ }
+ }
+ ///
+ /// [PointTrack] The maximum red color level (true color)
+ ///
+ public int PointTrackMaximumRedColorLevel
+ {
+ get
+ {
+ return pointTrackMaximumRedColorLevel;
+ }
+ set
+ {
+ if (value <= pointTrackMaximumRedColorLevel)
+ value = pointTrackMaximumRedColorLevel;
+ if (value > 255)
+ value = 255;
+ pointTrackMaximumRedColorLevel = value;
+ }
+ }
+ ///
+ /// [PointTrack] The maximum green color level (true color)
+ ///
+ public int PointTrackMaximumGreenColorLevel
+ {
+ get
+ {
+ return pointTrackMaximumGreenColorLevel;
+ }
+ set
+ {
+ if (value <= pointTrackMaximumGreenColorLevel)
+ value = pointTrackMaximumGreenColorLevel;
+ if (value > 255)
+ value = 255;
+ pointTrackMaximumGreenColorLevel = value;
+ }
+ }
+ ///
+ /// [PointTrack] The maximum blue color level (true color)
+ ///
+ public int PointTrackMaximumBlueColorLevel
+ {
+ get
+ {
+ return pointTrackMaximumBlueColorLevel;
+ }
+ set
+ {
+ if (value <= pointTrackMaximumBlueColorLevel)
+ value = pointTrackMaximumBlueColorLevel;
+ if (value > 255)
+ value = 255;
+ pointTrackMaximumBlueColorLevel = value;
+ }
+ }
+ ///
+ /// [PointTrack] The maximum color level (255 colors or 16 colors)
+ ///
+ public int PointTrackMaximumColorLevel
+ {
+ get
+ {
+ return pointTrackMaximumColorLevel;
+ }
+ set
+ {
+ int FinalMaximumLevel = 255;
+ if (value <= pointTrackMaximumColorLevel)
+ value = pointTrackMaximumColorLevel;
+ if (value > FinalMaximumLevel)
+ value = FinalMaximumLevel;
+ pointTrackMaximumColorLevel = value;
+ }
+ }
+ #endregion
}
}