Screensaver modding guide
What is the screensaver for the kernel?
The screensaver is the idle process that will activate if your computer went idle. You can also see the default screensaver by savescreen that is set by you or by the kernel.
The screensaver can also be customized, and we'll teach you how to make your first screensaver, to make from the simplest screensaver to legendary ones.
Basic modding (screensaver)
How to make your own screensavers on Visual Studio 2017?
Repeat steps 1-8 from the Modding guide
On the Compile section, click on Build Events, then write this on the Post-build event command line:
copy ....\ModFile.vb ........\ModFileSS.m (Put SS before the .m so that KS recognizes it as a screensaver and not as a mod)
del /Q . (to make sure that there is no dummy DLL files being created as we don't use DLL for mods)
Repeat steps 9-16 from the Modding guide, but replace the Imports KS.ModParser with Imports KS.Screensaver
Between the Public Class... and the End Class lines, let Visual Studio 2017 know that you're going to create your KS screensaver by writing: Implements ICustomSaver
If you're going to add namespaces, these rules must be met:
Don't import KS by itself. KS does that automatically
When importing modules/classes like TextWriterColor, it's written like this: Imports KS.TextWriterColor
Define properties for mod information by putting below the Implements IScript: Property Initialized As Boolean Implements ICustomSaver.Initialized
Make your init screensaver sub named InitSaver() that implements the ICustomSaver.InitSaver, by writing: Sub InitSaver() Implements ICustomSaver.InitSaver 'Your code here Initialized = True 'Put it anywhere in the sub if you're making If conditions, otherwise, leave it here. End Sub
Replace every Your code here comment with your code. Repeat this step on all the interface subs
Make your pre-display (Called before displaying screensaver) sub named PreDisplay() that implements the ICustomSaver.PreDisplay, by writing: Sub PreDisplay() Implements ICustomSaver.PreDisplay 'Your code here End Sub
Make your display code (it should display something) sub named ScrnSaver() that implements the ICustomSaver.ScrnSaver, by writing: Sub ScrnSaver() Implements ICustomSaver.ScrnSaver 'Your code here End Sub
You can make your subs anywhere on the class, but if:
they're on the different class, press Enter on End Class and make a public new class that stores new subs: Public Class AnotherClass 'Your definitions below, and so your subs, functions, interfaces, etc. End Class
they're trying to re-initialize the screensaver by re-calling InitSaver(), Try so on your test environment first, then the Production environment if that worked properly. And the following conditions should be met:
They shouldn't make an infinite loop unless you're making them that exits if specified conditions are met
They shouldn't try to cause errors with the kernel.
Put your sub call on one of the three subs that implements the ICustomSaver interface. Ex. If you're going to make a sub that's going to be called on screensaver display, place your sub call on the ScrnSaver() sub, and then your code on your sub.
Run the build. When the build is successful, ignore the dialog box that appears.
Run your Kernel Simulator you've just referenced to in your project, and load, set default, and lock your scren and your screensaver is there.
In-Console Message Box, and Soon, Overnight, or Rude (Go away...) messages
The back message box screensaver tells people that the computer owner is gone, or the owner tells that they should go away because there is important things going on in their computers. This is achieved in XLock in old Linux systems by putting 3 modes, Soon, Overnight, and Rude.
Right-click on the project, and go to Add > Class
Name your screensaver, but leave the .vb intact. Your mod name should be the one that is included in the Post-build built event. If your mod name is changed, you must also change the post-build event for the changes to be reflected.
Click Add, and the code will be ready.
Write below the (Assume that your mod name is SOR) Public Class SOR: Implements ICustomSaver
Write above the Public Class SOR:
Imports System
Imports System.Threading
Imports KS.Screensaver
Imports KS.TextWriterColor
Imports KS.Login
You should get errors saying that these subs should be created.
Make your start screensaver event handler by writing: Property Initialized As Boolean Implements ICustomSaver.Initialized Sub InitSaver() Implements ICustomSaver.InitSaver W("Load this screensaver using ""loadsaver SORSS.m"" and ""setsaver SORSS.m""", True, "neutralText") Initialized = True End Sub
Since we're not implementing anything before displaying screensaver, we're going to leave this blank: Sub PreDisplay() Implements ICustomSaver.PreDisplay End Sub
Write above the Property Initialized...: Public SOR_Random As New Random() 'Initializes the random number generator Public S_Random As New Random() 'Initializes the random number generator Public O_Random As New Random() 'Initializes the random number generator Public R_Random As New Random() 'Initializes the random number generator
Write on the ScrnSaver() sub: Console.Clear() If Custom.CancellationPending = True Then 'This will fix the issue for the task being busy. Exit For End If Dim SOR_Integer As Integer = SOR_Random.Next(1, 4) 'Chooses whether it's Soon, Overnight or Rude Dim Soon_MsgID As Integer = SOR_Random.Next(0, 2) 'Selects messages in the Soon array Dim Over_MsgID As Integer = SOR_Random.Next(0, 2) 'Selects messages in the Overnight array Dim Rude_MsgID As Integer = SOR_Random.Next(0, 3) 'Selects messages in the Rude array Console.SetWindowPosition(0, 1) Select Case SOR_Integer Case 1 'Soon WriteMsg(SOR_Integer, Soon_MsgID) Case 2 'Overnight WriteMsg(SOR_Integer, Over_MsgID) Case 3 'Rude WriteMsg(SOR_Integer, Rude_MsgID) End Select Thread.Sleep(10000)
You may need to create 1 function and 2 subs for this to work. Write them below the last End Sub: Public Shared Function ParsePlaces(ByVal text As String) text = text.Replace("", signedinusrnm) Return text End Function Public Shared Sub InitializeBar(ByVal strlen As Integer) W(" +-", "neutralText") For l As Integer = 0 To strlen - 1 W("-", "neutralText") Next W("-+", "neutralText") End Sub Public Shared Sub WriteMsg(ByVal TypeID As Integer, ByVal MsgID As Integer) Dim BackMessages As String() = {" will be back soon.", " is busy. He will be back soon."} Dim OvernightMsg As String() = {"It seems that will be back overnight", "He'll be back overnight."} Dim RudeMessages As String() = {"Can you go away?", "Go away, will be back soon", " isn't here. Go away."} Dim text As String = "" Select Case TypeID Case 1 text = ParsePlaces(BackMessages(MsgID)) Case 2 text = ParsePlaces(OvernightMsg(MsgID)) Case 3 text = ParsePlaces(RudeMessages(MsgID)) End Select InitializeBar(text.Length) W(" | {0} |", "neutralText", text) InitializeBar(text.Length) End Sub
The code should look like this: Imports System Imports System.Threading Imports KS.Screensaver Imports KS.TextWriterColor Imports KS.Login Public Class SoonOvernightRude Implements ICustomSaver Property Initialized As Boolean Implements ICustomSaver.Initialized Public SOR_Random As New Random() 'Initializes the random number generator Public S_Random As New Random() 'Initializes the random number generator Public O_Random As New Random() 'Initializes the random number generator Public R_Random As New Random() 'Initializes the random number generator Sub InitSaver() Implements ICustomSaver.InitSaver W("Set this screensaver as default using ""setsaver SORSS.m""", "neutralText") Initialized = True End Sub Sub PreDisplay() Implements ICustomSaver.PreDisplay End Sub Sub ScrnSaver() Implements ICustomSaver.ScrnSaver Console.Clear() If Custom.CancellationPending = True Then 'This will fix the issue for the task being busy. Exit For End If Dim SOR_Integer As Integer = SOR_Random.Next(1, 4) 'Chooses whether it's Soon, Overnight or Rude Dim Soon_MsgID As Integer = S_Random.Next(0, 2) 'Selects messages in the Soon array Dim Over_MsgID As Integer = O_Random.Next(0, 2) 'Selects messages in the Overnight array Dim Rude_MsgID As Integer = R_Random.Next(0, 3) 'Selects messages in the Rude array Console.SetCursorPosition(0, 1) Select Case SOR_Integer Case 1 'Soon WriteMsg(SOR_Integer, Soon_MsgID) Case 2 'Overnight WriteMsg(SOR_Integer, Over_MsgID) Case 3 'Rude WriteMsg(SOR_Integer, Rude_MsgID) End Select Thread.Sleep(10000) End Sub Public Shared Function ParsePlaces(ByVal text As String) text = text.Replace("", signedinusrnm) Return text End Function Public Shared Sub InitializeBar(ByVal strlen As Integer) W(" +-", "neutralText") For l As Integer = 0 To strlen - 1 W("-", "neutralText") Next W("-+", "neutralText") End Sub Public Shared Sub WriteMsg(ByVal TypeID As Integer, ByVal MsgID As Integer) Dim BackMessages As String() = {" will be back soon.", " is busy. He will be back soon."} Dim OvernightMsg As String() = {"It seems that will be back overnight", "He'll be back overnight."} Dim RudeMessages As String() = {"Can you go away?", "Go away, will be back soon", " isn't here. Go away."} Dim text As String = "" Select Case TypeID Case 1 text = ParsePlaces(BackMessages(MsgID)) Case 2 text = ParsePlaces(OvernightMsg(MsgID)) Case 3 text = ParsePlaces(RudeMessages(MsgID)) End Select InitializeBar(text.Length) W(" | {0} |", "neutralText", text) InitializeBar(text.Length) End Sub End Class
Run the build. When the build is successful, ignore the dialog box that appears.
Run your Kernel Simulator you've just referenced to in your project, and load, set as default, and run savescreen.
Simple Blank screen
Repeat the steps 1-4 on the first example: In-Console Message Box, and Soon, Overnight, or Rude (Go away...) messages
Write above the Public Class Blank (assuming that your classname is Blank):
Imports System
Imports KS.Screensaver
Write these below the Implements ICustomSaver: Public Property Initialized As Boolean Implements ICustomSaver.Initialized Public Sub InitSaver() Implements ICustomSaver.InitSaver Initialized = True End Sub Public Sub PreDisplay() Implements ICustomSaver.PreDisplay End Sub Public Sub ScrnSaver() Implements ICustomSaver.ScrnSaver
End Sub
Write inside the ScrnSaver sub: Console.Clear()
The code should look like this: Imports System Imports KS.Screensaver Public Class Blank Implements ICustomSaver Public Property Initialized As Boolean Implements ICustomSaver.Initialized Public Sub InitSaver() Implements ICustomSaver.InitSaver Initialized = True End Sub Public Sub PreDisplay() Implements ICustomSaver.PreDisplay End Sub Public Sub ScrnSaver() Implements ICustomSaver.ScrnSaver Console.Clear() End Sub End Class
Repeat the steps 13-14 on the first example: In-Console Message Box, and Soon, Overnight, or Rude (Go away...) messages
Animation (Drawing Circle - 4 frames - 4 FPS)
This example will get you started with the animations. Copy-paste the code for remaining examples.
Imports System Imports Microsoft.VisualBasic.Constants Imports KS.TextWriterColor Imports System.Threading Imports KS.Screensaver Public Class ANI Implements ICustomSaver Public Property Initialized As Boolean Implements ICustomSaver.Initialized Public CurrentStep As Integer Public Sub InitSaver() Implements ICustomSaver.InitSaver Initialized = True End Sub Public Sub PreDisplay() Implements ICustomSaver.PreDisplay End Sub Public Sub ScrnSaver() Implements ICustomSaver.ScrnSaver For CurrentStep = 0 To 3 Console.Clear() If Custom.CancellationPending = True Then 'This will fix the issue for the task being busy. Exit For End If W(aniset(CurrentStep), "neutralText") Thread.Sleep(150) Next End Sub
End Class
Calculate from 0 to 1,000,000 with progress bar (dynamic)
Imports System Imports Microsoft.VisualBasic.Constants Imports KS.TextWriterColor Imports Microsoft.VisualBasic.Strings Imports KS.Screensaver Public Class Dynamic Implements ICustomSaver Public Property Initialized As Boolean Implements ICustomSaver.Initialized Public Res As Integer Public ProgWent As Integer Public Check As Integer Public oldCheck As Integer Public Sub InitSaver() Implements ICustomSaver.InitSaver Initialized = True End Sub Public Sub PreDisplay() Implements ICustomSaver.PreDisplay End Sub Public Sub ScrnSaver() Implements ICustomSaver.ScrnSaver Console.Clear() For Res = 0 To 1000000 If Custom.CancellationPending = True Then 'This will fix the issue for the task being busy. Exit For End If Console.SetCursorPosition((Console.WindowWidth / 2) - 9, (Console.WindowHeight / 2) - 5) ShowStats() Next Check = 0 : oldCheck = 0 : ProgWent = 0 End Sub Public Sub ShowStats() W("{0} / 1000000 | {1}%", "neutralText", Res, FormatNumber(CStr(Res * 100 / 1000000), 1)) UpdateProgressBar(Res * 100 / 1000000) End Sub Public Sub UpdateProgressBar(ByVal percent As String) Check = percent / 5 W(Check, "neutralText") Console.SetCursorPosition((Console.WindowWidth / 2) - 9, (Console.WindowHeight / 2) - 3) W("+--------------------+", "neutralText") Console.SetCursorPosition((Console.WindowWidth / 2) - 9, (Console.WindowHeight / 2) - 2) W("| ", "neutralText") If Check <> oldCheck Then For Went As Integer = 0 To ProgWent W("*", "neutralText") Next ProgWent += 1 End If Console.SetCursorPosition((Console.WindowWidth / 2) + 11, (Console.WindowHeight / 2) - 2) W(" |", "neutralText") Console.SetCursorPosition((Console.WindowWidth / 2) - 9, (Console.WindowHeight / 2) - 1) W("+--------------------+", "neutralText") oldCheck = percent / 5 End Sub End Class
More examples
If you want to check out more examples, feel free to check them out in the KSModExamples respository on Screensavers folder in GitHub.
Last updated