I once saw a really cool Linux screen saver while working in the Linux labs at school. It had a bunch of colored numbers and letters all over the screen which periodically pulsed and changed. I could tell it was some kind of program interpreter and that the cycling pulses were running code, but beyond that I didn't have a clue.
Some time later (and not too long ago), I had the urge to write a similar screen saver. My friend shot down my ideas one by one and then suggested I do a port of the original Linux screen saver. That's precisely what I've done.
The Windows Virtual Machine (WVM) screen saver is distributed under the GNU General Public License (GPL). It requires at least Windows NT 4.0 and DirectX 8.0 to run. The source code is provided in Visual C++ 6.0 format. The original screen saver was written by Artur Rataj and is called KVM.
If you want to get the screen saver up and running, extract wvm.scr to your system directory (probably C:\WINDOWS\SYSTEM32). Then right-click on the Desktop, select Properties, and click on the Screen Saver tab. Select the Virtual Machine screen saver from the list. You can now click Settings to change the simulation parameters, click Test to see the screen saver, and click OK to set this as your screen saver.
For details on what the screen saver actually does, click on Help in the Settings dialog. There's a rather exhaustive explanation from the user's perspective there. What follows is an overview from the programmer's perspective.
The screen saver is divided into four main modules:
- Display.cpp / Display.h
- ScreenSaver.cpp / ScreenSaver.h
- Settings.cpp / Settings.h
- Simulator.cpp / Simulator.h
This is the entry point module. Screen savers that link with scrnsave.lib are required to implement the
ScreenSaverProc function. This function is called when the screen saver is started and terminated. Because the screen saver needs to enter a constantly running loop to function, this function starts a thread which handles the rest of the screen saver and returns immediately. Upon termination, it destroys the thread and ends the screen saver.
The thread creates an instance of the
ScreenSaver class, which is a singleton (only one instance can exist at a time). It then calls the
Heartbeat function, which is the screen saver's main loop, on that instance. This loop continually updates the virtual machine by calling
Behave on it and then requesting a screen paint.
The settings dialog and registry reading and writing is handled by this module.
ScreenSaverConfigureDialog, another required screen saver function, is augmented by a static
Settings object. This module could probably use a little tidying up but it does the job well.
Nearly all of the DirectX code is contained in this module. The item of interest is the singleton
Display class. The code is very minimal because screen savers don't have to deal with losing the device. The constructor initializes Direct3D and the device, the
Paint function prepares the device for painting, and the
Blt function does a nicely versatile job of painting 2D sprites.
This module is the core of the screen saver. Much of the code was taken directly from the Linux original. If you want to really understand it, you'll have to get into the code. I'll point out major landmarks though.
Behave is called each time the main loop repeats. It in turn calls
DoCycle which updates the state of the virtual machine. It also updates all the effects.
Effects are an addition I made to the screen saver that are not found in the original. In essence, the effects are a linked list of
structs. They are updated separately from the virtual machine itself and are painted on top of it.
So that's an overview of the Windows Virtual Machine screen saver. You'll get the most benefit from it by rummaging through the code yourself. Feel free to ask any specific questions and I will go into greater detail.